utili.h
包含要用到的头文件,在此头文件中
#ifndef _UTILI_H
#define _UTILI_H
#include<iostream>
#include<assert.h>
#include<stdlib.h>
#include<time.h>
#include<string.h>
using namespace std;
typedef unsigned char u_char;
typedef unsigned long u_long;
typedef enum{POSITIVE, NEGATIVE}Symbol;
#endif
SeqList.h
大数存储结构的实现
#pragma once
#include"utili.h"
class BigInt;
template<class Type>
class SeqList
{
friend class BigInt;
public:
SeqList(size_t sz = DEFAULT_SIZE);
SeqList(const SeqList<Type> &bt);
SeqList& operator=(const SeqList<Type> &st);
~SeqList();
public:
typedef Type& reference;
typedef const Type& const_reference;
public:
void push_back(const Type &x);
void push_front(const Type &x);
void pop_back();
void pop_front();
reference front();
reference back();
const_reference back()const;
const_reference front()const;
size_t size()const;
void reverse();
void clear();
void sort();
int find(const Type &key);
void erase(const Type &key);
public:
reference operator[](int pos);
const_reference operator[](int pos)const;
public:
bool Inc()
{
capacity += INC_SIZE;
Type *new_base = new Type[capacity+1];
if(NULL == new_base)
{
cout<<"Out Of Memory."<<endl;
//exit(1);
return false;
}
memset(new_base, 0, sizeof(Type)*(capacity+1));
memcpy(new_base, base, sizeof(Type)*(capacity-INC_SIZE+1));
delete []base;
base = new_base;
return true;
}
public:
void SetSymbol(Symbol sign);
Symbol GetSymbol()const;
private:
enum{DEFAULT_SIZE = 10, INC_SIZE = 5};
Type *base;
size_t capacity;
size_t len;
};
///////////////////////////////////////////////////////////////
template<class Type>
SeqList<Type>::SeqList(size_t sz)
{
capacity = sz > DEFAULT_SIZE ? sz : DEFAULT_SIZE;
base = new Type[capacity+1];
memset(base, 0, sizeof(Type) * (capacity+1));
len = 0;
}
template<class Type>
SeqList<Type>::SeqList(const SeqList<Type> &bt)
{
capacity = bt.capacity;
base = new Type[sizeof(Type)*(capacity+1)];
memset(base, 0, sizeof(Type)*(capacity+1));
memcpy(base, bt.base, sizeof(Type)*(bt.len+1));
len = bt.len;
}
//bt = bt1;
template<class Type>
SeqList<Type>& SeqList<Type>::operator=(const SeqList<Type> &st)
{
if(this != &st)
{
if(capacity < st.len)
{
delete []base;
base = new Type[st.capacity+1];
capacity = st.capacity;
}
memcpy(base, st.base, sizeof(Type)*(st.len+1));
len = st.len;
}
return *this;
}
template<class Type>
SeqList<Type>::~SeqList()
{
delete []base;
base = NULL;
capacity = len = 0;
}
template<class Type>
void SeqList<Type>::SetSymbol(Symbol sign)
{
base[0] = sign;
}
template<class Type>
Symbol SeqList<Type>::GetSymbol()const
{
return (Symbol)base[0];
}
template<class Type>
void SeqList<Type>::push_back(const Type &x)
{
//assert(len < capacity);
if(len>=capacity && !Inc())
return;
base[++len] = x;
}
template<class Type>
void SeqList<Type>::push_front(const Type &x)
{
//assert(len < capacity);
if(len>=capacity && !Inc())
return;
for(int i=++len; i>1; --i)
{
base[i] = base[i-1];
}
base[1] = x;
}
template<class Type>
void SeqList<Type>::pop_back()
{
assert(len > 0);
--len;
}
template<class Type>
void SeqList<Type>::pop_front()
{
assert(len > 0);
for(int i=1; i<len; ++i)
{
base[i] = base[i+1];
}
--len;
}
template<class Type>
typename SeqList<Type>::reference SeqList<Type>::front()
{
assert(len > 0);
return base[1];
}
template<class Type>
typename SeqList<Type>::reference SeqList<Type>::back()
{
assert(len > 0);
return base[len];
}
template<class Type>
typename SeqList<Type>::const_reference SeqList<Type>::front()const
{
assert(len > 0);
return base[1];
}
template<class Type>
typename SeqList<Type>::const_reference SeqList<Type>::back()const
{
assert(len > 0);
return base[len];
}
template<class Type>
size_t SeqList<Type>::size()const
{
return len;
}
template<class Type>
void SeqList<Type>::reverse()
{
if(len == 1)
return;
int low = 1;
int high = len;
Type tmp;
while(low < high)
{
tmp = base[low];
base[low] = base[high];
base[high] = tmp;
low++;
high--;
}
}
template<class Type>
void SeqList<Type>::clear()
{
len = 0;
}
template<class Type>
void SeqList<Type>::sort()
{
if(len == 1)
return;
for(int i=0; i<len-1; ++i)
{
for(int j=1; j<=len-i-1; ++j)
{
if(base[j] > base[j+1])
{
Type tmp = base[j];
base[j] = base[j+1];
base[j+1] = tmp;
}
}
}
}
template<class Type>
int SeqList<Type>::find(const Type &key)
{
for(int i=1; i<=len; ++i)
{
if(key == base[i])
return i;
}
return -1;
}
template<class Type>
void SeqList<Type>::erase(const Type &key)
{
int pos = find(key);
if(pos == -1)
return;
for(int i=pos; i<len; ++i)
{
base[i] = base[i+1];
}
--len;
}
template<class Type>
typename SeqList<Type>::reference SeqList<Type>::operator[](int pos)
{
assert(pos>=1 && pos<=len);
return base[pos];
}
template<class Type>
typename SeqList<Type>::const_reference SeqList<Type>::operator[](int pos)const
{
assert(pos>=1 && pos<=len);
return base[pos];
}
BingInt.h
#pragma once
#include"utili.h"
#include"SeqList.h"
class BigInt;
ostream& operator<<(ostream &out, const BigInt &bt);
class BigInt
{
friend ostream& operator<<(ostream &out, const BigInt &bt);
public:
BigInt(long value = 0);
BigInt& operator=(u_long value);
public:
void LoadData(size_t sz);
void PrintData()const;
public:
void Clear();
void BigIntCopy(char *buf, size_t len, size_t &pos);
public:
u_char back()const;
void pop_back();
size_t size()const;
void clear();
void clear_head_zero();
void push_back(u_char x);
void push_front(u_char x);
public:
void SetSymbol(Symbol sign);
Symbol GetSymbol()const;
public:
static u_char AddItem(u_char a, u_char b, u_char &sign);
static u_char SubItem(u_char a, u_char b, u_char &sign);
static void MulItem(BigInt &bt, const BigInt &bt1, u_char x);
static void AddMove(BigInt &bt, const BigInt &bt1, int offset);
public:
//bt = bt1 + bt2;
static void Add(BigInt &bt, const BigInt &bt1, const BigInt &bt2);
static void Sub(BigInt &bt, const BigInt &bt1, const BigInt &bt2);
static void Mul(BigInt &bt, const BigInt &bt1, const BigInt &bt2);
static void Div(BigInt &bt, const BigInt &bt1, const BigInt &bt2);
static void Mod(BigInt &bt, const BigInt &bt1, const BigInt &bt2);
static void Square(BigInt &bt, const BigInt &bt1);//bt = bt1^2;
static void Power(BigInt &bt, const BigInt &bt1, u_long n);// bt = bt1^n;
static void Power(BigInt &bt, const BigInt &bt1, const BigInt &bt2);//bt = bt1^bt2
static void PowMod(BigInt &bt, BigInt &a, BigInt &b, const BigInt &n); //bt = bt1^bt2%bt3 //RSA
public:
u_char& operator[](int pos);
const u_char& operator[](int pos)const;
public:
BigInt operator+(const BigInt &bt);
BigInt operator-(const BigInt &bt);
BigInt operator*(const BigInt &bt);
BigInt operator/(const BigInt &bt);
BigInt operator%(const BigInt &bt);
public:
BigInt& operator++();
BigInt operator++(int);
BigInt& operator--();
BigInt operator--(int);
public:
BigInt& operator+=(const BigInt &bt);
BigInt& operator-=(const BigInt &bt);
BigInt& operator*=(const BigInt &bt);
BigInt& operator/=(const BigInt &bt);
BigInt& operator%=(const BigInt &bt);
public:
bool operator>(const BigInt &bt)const;
bool operator<(const BigInt &bt)const;
bool operator>=(const BigInt &bt)const;
bool operator<=(const BigInt &bt)const;
bool operator==(const BigInt &bt)const;
bool operator!=(const BigInt &bt)const;
public:
bool operator>(u_long x)const;
bool operator&(u_long x);
private:
SeqList<u_char> big;
};
BigInt.cpp
#include"BigInt.h"
ostream& operator<<(ostream &out, const BigInt &bt)
{
if(bt.GetSymbol() == NEGATIVE)
cout<<"-";
for(size_t i=bt.size(); i>=1; --i)
{
out<<(int)bt[i];
}
return out;
}
void BigInt::SetSymbol(Symbol sign)
{
big.SetSymbol(sign);
}
Symbol BigInt::GetSymbol()const
{
return big.GetSymbol();
}
BigInt::BigInt(long value)
{
SetSymbol(POSITIVE);
if(value == 0)
{
push_back(0);
}
else
{
if(value < 0)
{
SetSymbol(NEGATIVE);
value = abs(value);
}
while(value > 0)
{
push_back(value % 10);
value /= 10;
}
}
}
//bt = 123
BigInt& BigInt::operator=(u_long value)
{
(*this).clear();
if(value == 0)
{
push_back(0);
}
else
{
while(value > 0)
{
push_back(value % 10);
value /= 10;
}
}
return *this;
}
/////////////////////////////////////////////////////////
void BigInt::LoadData(size_t sz)
{
clear();
srand(time(NULL));
for(int i=0; i<sz; ++i)
{
big.push_back(rand()%10);
}
clear_head_zero();
}
void BigInt::PrintData()const
{
for(int i=size(); i>=1; --i)
{
cout<<(int)big[i];
}
cout<<endl;
}
////////////////////////////////////////////////////////////
void BigInt::Clear()
{
big.clear();
}
void BigInt::BigIntCopy(char *buf, size_t len, size_t &pos)
{
if(pos == 0)
{
memcpy(buf,big.base,1); //copy 0 index
pos++;
}
memcpy(buf,big.base+pos, len);
}
////////////////////////////////////////////////////////////
u_char BigInt::back()const
{
return big.back();
}
void BigInt::pop_back()
{
big.pop_back();
}
size_t BigInt::size()const
{return big.size();}
void BigInt::clear()
{big.clear();}
void BigInt::push_back(u_char x)
{
big.push_back(x);
}
void BigInt::push_front(u_char x)
{
big.push_front(x);
}
void BigInt::clear_head_zero()
{
while(size()>0 && *this!=0 && (*this).back() == 0)
{
pop_back();
}
}
////////////////////////////////////////////////////////////
u_char& BigInt::operator[](int pos)
{return big[pos];}
const u_char& BigInt::operator[](int pos)const
{return big[pos];}
bool BigInt::operator>(const BigInt &bt)const
{
if(size() > bt.size())
return true;
else if(size() < bt.size())
return false;
size_t i = size();
while(i >= 1)
{
if((*this)[i] > bt[i])
return true;
else if((*this)[i] < bt[i])
return false;
--i;
}
return false;
}
bool BigInt::operator<=(const BigInt &bt)const
{
return !(*this > bt);
}
bool BigInt::operator<(const BigInt &bt)const
{
if(size() < bt.size())
return true;
else if(size() > bt.size())
return false;
size_t i = size();
while(i >= 1)
{
if((*this)[i] < bt[i])
return true;
else if((*this)[i] > bt[i])
return false;
--i;
}
return false;
}
bool BigInt::operator>=(const BigInt &bt)const
{
return !(*this < bt);
}
bool BigInt::operator==(const BigInt &bt)const
{
if(size() != bt.size())
return false;
size_t i = 1;
while(i <= size())
{
if((*this)[i] != bt[i])
return false;
++i;
}
return true;
}
bool BigInt::operator!=(const BigInt &bt)const
{
return !(*this == bt);
}
////////////////////////////////////////////////////////////
bool BigInt::operator>(u_long x)const
{
BigInt tmp(x);
return *this > tmp;
}
////////////////////////////////////////////////////////////
BigInt& BigInt::operator++()
{
u_char sign = 1;
size_t i = 1;
while(sign>0 && i<=size())
{
(*this)[i] = AddItem((*this)[i], 0, sign);
++i;
}
if(sign > 0)
push_back(sign);
return *this;
}
BigInt BigInt::operator++(int)
{
BigInt tmp = *this;
++*this;
return tmp;
}
BigInt& BigInt::operator--()
{
assert(*this > 0);
u_char sign = 1;
size_t i = 1;
while(sign>0 && i<=size())
{
(*this)[i] = SubItem((*this)[i], 0, sign);
++i;
}
clear_head_zero();
return *this;
}
BigInt BigInt::operator--(int)
{
BigInt tmp = *this;
--*this;
return tmp;
}
////////////////////////////////////////////////////////////
//123 417491941949
BigInt& BigInt::operator+=(const BigInt &bt)
{
u_char sign = 0;
size_t i=1, j=1;
while(i<=size() && j<=bt.size())
{
(*this)[i] = AddItem((*this)[i], bt[j], sign);
++i;
++j;
}
while(sign>0 && i<=size())
{
(*this)[i] = AddItem((*this)[i], 0, sign);
++i;
}
while(j <= bt.size())
{
u_char sum = AddItem(0, bt[j], sign);
push_back(sum);
++j;
}
if(sign > 0)
push_back(sign);
return *this;
}
BigInt& BigInt::operator-=(const BigInt &bt)
{
assert(*this >= bt);
if(*this == bt)
{
*this = 0;
return *this;
}
else
{
u_char sign = 0;
size_t i=1, j=1;
while(i<=size() && j<=bt.size())
{
(*this)[i] = SubItem((*this)[i], bt[j], sign);
++i;
++j;
}
while(sign>0 && i<=size())
{
(*this)[i] = SubItem((*this)[i], 0, sign);
++i;
}
}
return *this;
}
BigInt& BigInt::operator*=(const BigInt &bt)
{
BigInt tmp;
BigInt::Mul(tmp, *this, bt);
*this = tmp;
return *this;
}
BigInt& BigInt::operator/=(const BigInt &bt)
{
BigInt tmp;
BigInt::Div(tmp, *this, bt);
*this = tmp;
return *this;
}
BigInt& BigInt::operator%=(const BigInt &bt)
{
BigInt tmp;
BigInt::Mod(tmp, *this, bt);
*this = tmp;
return *this;
}
////////////////////////////////////////////////////////////
BigInt BigInt::operator+(const BigInt &bt)
{
BigInt tmp;
BigInt::Add(tmp, *this, bt);
return tmp;
}
BigInt BigInt::operator-(const BigInt &bt)
{
BigInt tmp;
BigInt::Sub(tmp, *this, bt);
return tmp;
}
BigInt BigInt::operator*(const BigInt &bt)
{
BigInt tmp;
BigInt::Mul(tmp, *this, bt);
return tmp;
}
BigInt BigInt::operator/(const BigInt &bt)
{
BigInt tmp;
BigInt::Div(tmp, *this, bt);
return tmp;
}
BigInt BigInt::operator%(const BigInt &bt)
{
BigInt tmp;
BigInt::Mod(tmp, *this, bt);
return tmp;
}
////////////////////////////////////////////////////////////
bool BigInt::operator&(u_long x)
{
BigInt tmp(2);
BigInt ans = *this % tmp;
return ans==1;
}
////////////////////////////////////////////////////////////
u_char BigInt::AddItem(u_char a, u_char b, u_char &sign)
{
u_char sum = a + b + sign;
if(sum >= 10)
{
sum -= 10;
sign = 1;
}
else
sign = 0;
return sum;
}
void BigInt::Add(BigInt &bt, const BigInt &bt1, const BigInt &bt2)
{
bt.clear();
u_char sum, sign = 0;
size_t i=1, j=1;
while(i<=bt1.size() && j<=bt2.size())
{
sum = AddItem(bt1[i],bt2[j],sign);
bt.push_back(sum);
++i;
++j;
}
while(i <= bt1.size())
{
sum = AddItem(bt1[i], 0, sign);
bt.push_back(sum);
++i;
}
while(j <= bt2.size())
{
sum = AddItem(0, bt2[j], sign);
bt.push_back(sum);
++j;
}
if(sign > 0)
bt.push_back(sign);
}
u_char BigInt::SubItem(u_char a, u_char b, u_char &sign)
{
u_char sub;
if(a >= b+sign)
{
sub = a - b - sign;
sign = 0;
}
else
{
sub = a + 10 - b - sign;
sign = 1;
}
return sub;
}
void BigInt::Sub(BigInt &bt, const BigInt &bt1, const BigInt &bt2)
{
bt.clear();
if(bt1 < bt2)
return;
if(bt1 == bt2)
bt = 0;
u_char sub, sign = 0;
size_t i=1, j=1;
while(i<=bt1.size() && j<=bt2.size())
{
sub = SubItem(bt1[i], bt2[j], sign);
bt.push_back(sub);
++i;
++j;
}
while(i<=bt1.size())
{
sub = SubItem(bt1[i], 0, sign);
bt.push_back(sub);
++i;
}
bt.clear_head_zero();
}
void BigInt::MulItem(BigInt &bt, const BigInt &bt1, u_char x)
{
u_char mul, sign = 0;
size_t i = 1;
while(i <= bt1.size())
{
mul = bt1[i] * x + sign; //4 5
if(mul >= 10)
{
sign = mul / 10;
mul %= 10;
}
else
sign = 0;
bt.push_back(mul);
++i;
}
if(sign > 0)
bt.push_back(sign);
}
void BigInt::AddMove(BigInt &bt, const BigInt &bt1, int offset)
{
u_char sign = 0;
size_t i = offset;
size_t j = 1;
while(i<=bt.size() && j<=bt1.size())
{
bt[i] = AddItem(bt[i], bt1[j], sign);
++i;
++j;
}
while(sign>0 && i<=bt.size())
{
bt[i] = AddItem(bt[i], 0, sign);
++i;
}
while(j <= bt1.size())
{
u_char sum = AddItem(0, bt1[j], sign);
bt.push_back(sum);
++j;
}
if(sign > 0)
bt.push_back(sign);
}
void BigInt::Mul(BigInt &bt, const BigInt &bt1, const BigInt &bt2)
{
BigInt tmp;
for(size_t i=1; i<=bt2.size(); ++i)
{
tmp.clear();
MulItem(tmp, bt1, bt2[i]);
AddMove(bt, tmp, i);
}
}
void BigInt::Div(BigInt &bt, const BigInt &bt1, const BigInt &bt2)
{
bt = 0;
if(bt1 < bt2)
bt = 0;
else if(bt1 == bt2)
bt = 1;
else
{
size_t bt1_len = bt1.size();
size_t bt2_len = bt2.size();
int k = bt1_len - bt2_len;
BigInt btd;
btd.clear();
for(size_t i=1; i<=bt2.size(); ++i)
{
btd.push_back(bt1[i+k]);
}
u_char div = 0;
while(k >= 0)
{
while(btd >= bt2)
{
btd -= bt2;
div++;
btd.clear_head_zero();
}
bt.push_front(div);
div = 0;
if(k > 0)
btd.push_front(bt1[k]);
--k;
}
bt.clear_head_zero();
}
}
void BigInt::Mod(BigInt &bt, const BigInt &bt1, const BigInt &bt2)
{
bt = 0;
if(bt1 < bt2)
bt = bt1;
else if(bt1 == bt2)
bt = 0;
else
{
size_t bt1_len = bt1.size();
size_t bt2_len = bt2.size();
int k = bt1_len - bt2_len;
BigInt btd;
btd.clear();
for(size_t i=1; i<=bt2.size(); ++i)
{
btd.push_back(bt1[i+k]);
}
while(k >= 0)
{
while(btd >= bt2)
{
btd -= bt2;
btd.clear_head_zero();
}
if(k > 0)
btd.push_front(bt1[k]);
--k;
}
bt = btd;
bt.clear_head_zero();
}
}
void BigInt::Square(BigInt &bt, const BigInt &bt1)
{
BigInt::Mul(bt, bt1, bt1);
}
void BigInt::Power(BigInt &bt, const BigInt &bt1, u_long n)
{
bt = 1;
for(u_long i=0; i<n; ++i)
{
bt *= bt1;
}
}
void BigInt::Power(BigInt &bt, const BigInt &bt1, const BigInt &bt2)
{
bt = 1;
for(BigInt i=0; i<bt2; ++i)
{
bt *= bt1;
}
}
//ACM a^b%c
void BigInt::PowMod(BigInt &bt, BigInt &a, BigInt &b, const BigInt &n)
{
BigInt ans = 1;
a %= n;
while(b != 0)
{
if(b & 1)
{
ans = (ans * a) % n;
}
a = (a*a) % n;
b = b / 2;
}
bt = ans;
bt.clear_head_zero();
}
/*
//RSA bt = a^b % n
void BigInt::PowMod(BigInt &bt, BigInt &a, BigInt &b, const BigInt &n)
{
BigInt tmp;
BigInt::Power(tmp, a, b);
BigInt::Mod(bt, tmp, n);
}
*/
下面的文件是实现BigInt.cgi
BigIntSer.cpp
#include<iostream>
#include<unistd.h>
#include<stdio.h>
#include"./BigInt/BigInt.h"
using namespace std;
typedef enum {ADD=1,SUB, MUL, DIV} OPER;
void Html_Header()
{
printf("Content-Type:text/html;charset=utf-8\n\n");
printf("<title>51CC BigInt</title>");
printf("<H1 align=center>WelCome To 51CC.</H1>");
}
void Data_Handler(BigInt &bt, BigInt &bt1, BigInt &bt2, OPER &oper)
{
bt.clear();
bt1.clear();
bt2.clear();
char *data = getenv("QUERY_STRING");
//printf("<p>data = %s<br>",data);
if(data == NULL)
printf("<p> 接收数据出错.");
else
{
while(*data!='\0' && *data!='&')
{
if(*data>='0' && *data<='9')
bt1.push_front(*data-'0');
++data;
}
data++;
while(*data!='\0' && *data!='&')
{
if(*data>='0' && *data<='9')
bt2.push_front(*data-'0');
++data;
}
while(*data != '\0')
{
if(*data == '1')
{
oper = ADD;
break;
}
else if(*data == '2')
{
oper = SUB;
break;
}
else if(*data == '3')
{
oper = MUL;
break;
}
else if(*data == '4')
{
oper = DIV;
break;
}
else
data++;
}
}
///////////////////////////////////////////////////////////
if(oper == ADD)
bt = bt1 + bt2;
else if(oper == SUB)
bt = bt1 - bt2;
else if(oper == MUL)
bt = bt1 * bt2;
else if(oper == DIV)
bt = bt1 / bt2;
}
void Show_Result(const BigInt &bt, const BigInt &bt1, const BigInt &bt2, OPER oper)
{
printf("<br>");
printf("<div style='word-wrap:break-word;font-size:30px;font-weight:blod;' align=center>bt1=");
for(int i=bt1.size(); i>=1; --i)
printf("%d", bt1[i]);
printf("<br>");
if(oper == ADD)
printf("+<br>");
else if(oper == SUB)
printf("-<br>");
else if(oper == MUL)
printf("*<br>");
else if(oper == DIV)
printf("/<br>");
printf("bt2=");
for(int i=bt2.size();i>=1; --i)
printf("%d", bt2[i]);
printf("<br>");
//printf("result = ");
printf("||<br>");
for(int i=bt.size(); i>=1; --i)
printf("%d", bt[i]);
printf("</div>");
}
int main(int argc, char* argv[])
{
Html_Header();
BigInt bt, bt1, bt2;
OPER oper;
Data_Handler(bt, bt1, bt2, oper);
Show_Result(bt, bt1, bt2, oper);
return 0;
}
sock.h
#ifndef _SOCK_H
#define _SOCK_H
#include"./BigInt/BigInt.h"
#include<unistd.h>
#include<stdlib.h>
#include<sys/types.h>
#include<sys/socket.h>
#include<netinet/in.h>
#include<arpa/inet.h>
#include<pthread.h>
#include<stdio.h>
#define SERVER_IP "127.0.0.1"
#define SERVER_PORT 5050
#define LISTEN_QUEUE 5
#define BUFFER_SIZE 32
typedef enum {ADD,SUB,MUL,DIV,QUIT}OPER_ENUM;
typedef struct BigIntOper
{
OPER_ENUM command;
BigInt *bt1;
BigInt *bt2;
}BigIntOper;
void SendData(int sockConn, BigInt *pbt);
void RecvData(int sockConn, BigInt &bt);
void* BigIntServer(void *arg);
#endif
sock.cpp
#include"sock.h"
#include<sys/types.h>
void SendData(int sockConn, BigInt *pbt)
{
u_long data_len = pbt->size();
send(sockConn,(char*)&data_len,sizeof(u_long),0);
char sendbuf[BUFFER_SIZE];
size_t len = 0;
size_t pos = 0;
while(data_len > 0)
{
len = data_len > BUFFER_SIZE ? BUFFER_SIZE : data_len;
data_len -= len;
//分片
pbt->BigIntCopy(sendbuf,len,pos);
send(sockConn,sendbuf,len,0);
pos += len;
}
}
void RecvData(int sockConn, BigInt &bt)
{
bt.Clear();
char recvbuf[BUFFER_SIZE];
u_long data_len;
u_long length;
memset(recvbuf,0,BUFFER_SIZE);
recv(sockConn,(char*)&data_len,sizeof(u_long),0);
//cout<<"data_len = "<<data_len<<endl;
if(data_len < BUFFER_SIZE)
length = recv(sockConn,recvbuf,data_len,0);
else
length = recv(sockConn,recvbuf,BUFFER_SIZE,0);
for(u_long i=0; i<length; ++i)
{
bt.push_back(recvbuf[i]);
}
while(length < data_len)
{
memset(recvbuf,0,BUFFER_SIZE);
data_len -= length;
if(data_len < BUFFER_SIZE)
length = recv(sockConn,recvbuf,data_len,0);
else
length = recv(sockConn,recvbuf,BUFFER_SIZE,0);
for(u_long i=0; i<length; ++i)
{
bt.push_back(recvbuf[i]);
}
}
}
void* BigIntServer(void *arg)
{
int sockConn = *(int*)arg;
int comm;
/////////////////////////////////////////////////////////////////////
BigInt bt;
BigInt bt1;
BigInt bt2;
/////////////////////////////////////////////////////////////////////
while(1)
{
recv(sockConn,(char*)&comm,sizeof(int),0);
cout<<"command : "<<comm<<endl;
RecvData(sockConn, bt1);
cout<<"bt1 = ";
bt1.PrintData();
RecvData(sockConn, bt2);
cout<<"bt2 = ";
bt2.PrintData();
switch(comm)
{
case ADD:
BigInt::Add(bt,bt1,bt2);
cout<<"result = "<<bt<<endl;
break;
case SUB:
BigInt::Sub(bt,bt1,bt2);
break;
case MUL:
BigInt::Mul(bt,bt1,bt2);
break;
case DIV:
//BigInt::Div(bt,bt1,bt2);
break;
default:
break;
}
SendData(sockConn, &bt);
}
close(sockConn);
pthread_exit(NULL);
}
int main(int argc, char *argv[])
{
if(argc != 3)
{
cout<<"Argument Error."<<endl;
cout<<"usage: BigIntSer ip port"<<endl;
return -1;
}
short port = atoi(argv[2]);
char *ip = argv[1];
int sockSer;
sockSer = socket(AF_INET, SOCK_STREAM, 0);
struct sockaddr_in addrSer,addrCli;
addrSer.sin_family = AF_INET;
addrSer.sin_port = htons(port);
addrSer.sin_addr.s_addr = inet_addr(ip);
bind(sockSer,(struct sockaddr*)&addrSer, sizeof(struct sockaddr));
listen(sockSer,LISTEN_QUEUE);
int len = sizeof(struct sockaddr);
int sockConn;
printf("Server Listen: ip=%s,port=%d.\n",ip,port);
while(1)
{
sockConn = accept(sockSer,(struct sockaddr*)&addrCli, (socklen_t*)(&len));
if(sockConn < 0)
{
cout<<"Server Accept Client Connect Fail!"<<endl;
continue;
}
else
{
cout<<"Server Accept Client Connect Success!"<<endl;
}
pthread_t tid;
int res = pthread_create(&tid, NULL, BigIntServer, (void*)&sockConn);
if(res != 0)
{
cout<<"Server Create Client Thread Failed!"<<endl;
}
else
{
cout<<"Server Create Client Thread Success!"<<endl;
}
}
close(sockSer);
return 0;
}
以上是针对数据库后台实现的代码,下面是BigInt_sql 的实现:
login.c
#include<stdio.h>
#include<unistd.h>
#include<mysql/mysql.h>
#include<stdlib.h>
int main()
{
printf("Content-Type:text/html;charset=utf-8\n\n");
MYSQL m_sql;
mysql_init(&m_sql);
MYSQL *sql = mysql_real_connect(&m_sql,"localhost","root","123","test",3306,NULL,0);
if(sql == NULL)
{
printf("<p>Connect Mysql Fail.\n");
exit(1);
}
char user[20] = {0};
char password[20] = {0};
int i = 0;
char *data = getenv("QUERY_STRING");
if(data == NULL)
printf("<p>接收数据出错.");
else
{
while(*data != '=')
data++;
data++; //skip =
while(*data != '&')
{
user[i++] = *data;
data++;
}
data++; //skip &
while(*data != '=')
data++;
data++; //skip =
i = 0;
while(*data != '\0')
{
password[i++] = *data;
data++;
}
}
MYSQL_ROW sqlrow;
MYSQL_RES *res_ptr;
char select[100] = {0};
sprintf(select,"select user_passwd from user_info where user_name='%s'",user);
int res = mysql_query(&m_sql, select);
res_ptr = mysql_store_result(&m_sql);
if(res_ptr)
{
sqlrow = mysql_fetch_row(res_ptr);
}
else
{
printf("<p>database data error.");
exit(1);
}
if(strcmp(sqlrow[0], password) == 0)
{
FILE *fp = fopen("./htdocs/bigcalc.html","r");
if(NULL == fp)
{
printf("<h1> Not Found 404</h1>");
exit(1);
}
char buf[128];
while(!feof(fp))
{
fgets(buf, 128, fp);
printf(buf);
}
fclose(fp);
}
else
{
printf("<p>user name or user password error.");
}
mysql_close(&m_sql);
return 0;
}
register.c
#include<stdio.h>
#include<unistd.h>
#include<stdlib.h>
#include<mysql/mysql.h>
int main()
{
printf("Content-Type:text/html;charset=utf-8\n\n");
MYSQL m_sql;
mysql_init(&m_sql);
MYSQL *sql = mysql_real_connect(&m_sql,"localhost","root","123","test",3306,NULL,0);
if(sql == NULL)
{
printf("<p>Connect Mysql Fail.\n");
exit(1);
}
char user[20] = {0};
char password[20] = {0};
int i = 0;
char *data = getenv("QUERY_STRING");
if(data == NULL)
printf("<p>接收数据出错.");
else
{
while(*data != '=')
data++;
data++; //skip =
while(*data != '&')
{
user[i++] = *data;
data++;
}
data++; //skip &
while(*data != '=')
data++;
data++; //skip =
i = 0;
while(*data != '\0')
{
password[i++] = *data;
data++;
}
}
//printf("<p>user_name = %s, user_passwd=%s",user,password);
//char sql[100] = {0};
//sprintf(sql, "insert into user_info values ('%s','%s');", user, password);
char query_sql[100] = {0};
sprintf(query_sql, "insert into user_info values ('%s','%s');", user, password);
mysql_query(&m_sql, query_sql);
mysql_close(&m_sql);
//printf("<p> Register Success.");
//sleep(1);
FILE *fp = fopen("./htdocs/index.html","r");
if(NULL == fp)
{
printf("<h1> Not Found 404</h1>");
exit(1);
}
char buf[128];
while(!feof(fp))
{
fgets(buf, 128, fp);
printf(buf);
}
fclose(fp);
return 0;
}
html 前端实现效果:
最终可以在网页上计算任意位数的大数据运算,包括加减乘除平方取模等.............