不研究TCP/IP协议,没有三次握手,不说 物数网传会表应(只要大学学过计算机基础的都背过吧!)这七层。
封装好socket。
server:
class ServerSock { public: ServerSock(); ~ServerSock(); SOCKET getClient() {return sClient;}; private: static const int PORT = 10086; int retVal; //返回值 SOCKET sServer; //服务器套接字 SOCKET sClient; //客户端套接字 SOCKADDR_IN addrServ;; //服务器地址 }; ServerSock::ServerSock() { WSADATA wsd; //WSADATA变量 //初始化套结字动态库 if (WSAStartup(MAKEWORD(2,2), &wsd) != 0) { cout << "WSAStartup failed!" << endl; } //创建套接字 sServer = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); if(INVALID_SOCKET == sServer) { cout << "socket failed!" << endl; WSACleanup();//释放套接字资源; } //服务器套接字地址 addrServ.sin_family = AF_INET; addrServ.sin_port = htons(PORT); addrServ.sin_addr.s_addr = INADDR_ANY; //绑定套接字 retVal = bind(sServer, (LPSOCKADDR)&addrServ, sizeof(SOCKADDR_IN)); if(SOCKET_ERROR == retVal) { cout << "bind failed!" << endl; closesocket(sServer); //关闭套接字 WSACleanup(); //释放套接字资源; } //开始监听 cout<<"start listen!"<<endl; retVal = listen(sServer, 1); if(SOCKET_ERROR == retVal) { cout << "listen failed!" << endl; closesocket(sServer); //关闭套接字 WSACleanup(); //释放套接字资源; } //接受客户端请求 sockaddr_in addrClient; int addrClientlen = sizeof(addrClient); sClient = accept(sServer,(sockaddr FAR*)&addrClient, &addrClientlen); cout<<"accept!"<<endl; if(INVALID_SOCKET == sClient) { cout << "accept failed!" << endl; closesocket(sServer); //关闭套接字 WSACleanup(); //释放套接字资源; } } ServerSock::~ServerSock() { closesocket(sServer); //关闭套接字 //closesocket(sClient); //关闭套接字 WSACleanup(); //释放套接字资源; }
client:
class ClientSock { public: ClientSock(); ~ClientSock(); SOCKET getClient() {return cClient;}; private: static const int PORT = 10086; int retVal; //返回值 SOCKET cClient; //客户端套接字 SOCKADDR_IN addrServ;; //服务器地址 }; ClientSock::ClientSock() { WSADATA wsd; //WSADATA变量 //初始化套结字动态库 if (WSAStartup(MAKEWORD(2,2), &wsd) != 0) { cout << "WSAStartup failed!" << endl; } //创建套接字 cClient = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); if(INVALID_SOCKET == cClient) { cout << "socket failed!" << endl; WSACleanup();//释放套接字资源; } //服务器套接字地址 addrServ.sin_family = AF_INET; addrServ.sin_port = htons(PORT); addrServ.sin_addr.s_addr = inet_addr(IP_ADDR); //绑定套接字 retVal = connect(cClient, (LPSOCKADDR)&addrServ, sizeof(SOCKADDR_IN)); if(SOCKET_ERROR == retVal) { cout << "connect failed!" << endl; closesocket(cClient); //关闭套接字 WSACleanup(); //释放套接字资源; } } ClientSock::~ClientSock() { //closesocket(cClient); //关闭套接字 WSACleanup(); //释放套接字资源; }
关于数据部分,两个是通用的
class SockData { public: SockData(SOCKET _client) { client = _client;}; ~SockData() { closesocket(client); }; bool sendData(const char sData); bool sendData(int sData); bool sendData(char* sData,int Len = BUFSIZE); bool sendData(const string sfileRoad); int recvData(); bool recvData(char* buf, int Len = BUFSIZE); bool recvData(const string rfileRoad); private: static const int BUFSIZE = 1024; //默认大小 int retVal; //返回值 SOCKET client; //客户端套接字 }; bool SockData::sendData(const char sData) { retVal = send(client,&sData,sizeof(char),0); if(retVal==SOCKET_ERROR) { cout<<"Send Into error: "<<GetLastError()<<endl; cout<<"Fail char: "<<sData<<endl; return false; } return true; } bool SockData::sendData(int sData) { stringstream strTemp;strTemp.clear();strTemp.str(""); strTemp << sData; const string sTemp = strTemp.str(); const char* cTemp = sTemp.c_str(); if(! sendData(char('0'+strlen(cTemp)))) { cout<<"In trouble"<<endl; } retVal = send(client,cTemp,sizeof(char) * strlen(cTemp),0); if(retVal==SOCKET_ERROR) { cout<<"Send Into error: "<<GetLastError()<<endl; cout<<"Fail int: "<<sData<<endl; return false; } return true; } bool SockData::sendData(char* sData,int Len) { retVal=send(client,sData,sizeof(char) * Len,0); if(retVal==SOCKET_ERROR) { cout<<"Send Into error: "<<GetLastError()<<endl; return false; } return true; } bool SockData::sendData(const string sfileRoad) { ifstream in(sfileRoad,fstream::in|fstream::binary); if(!in.is_open()) { cout<<"fail open file."<<endl; return false; } in.seekg (0, ios::end); int length = in.tellg(); in.seekg (0, ios::beg); sendData(length); char* buf = new char[BUFSIZE]; //接收数据缓冲区 ZeroMemory(buf, BUFSIZE); while(!in.eof()) { in.read(buf,BUFSIZE); retVal=send(client,buf,sizeof(char) * BUFSIZE,0); if(retVal==SOCKET_ERROR) { cout<<"Send Into error: "<<GetLastError()<<endl; return false; } } in.close(); delete[] buf; return true; } int SockData::recvData() { char intBit; retVal = recv(client,&intBit,sizeof(char),0); if(retVal == SOCKET_ERROR) { cout<<"Recv Into error: "<<GetLastError()<<endl; cout<<"Fail intBit!"<<endl; return false; } int Bit = atoi(&intBit); char* cInt = new char[Bit]; retVal = recv(client,cInt,sizeof(char) * Bit,0); if(retVal == SOCKET_ERROR) { cout<<"Recv Into error: "<<GetLastError()<<endl; cout<<"Fail intBit!"<<endl; return false; } int rData = atoi(cInt); delete[] cInt; return rData; } bool SockData::recvData(char* buf, int Len) { ZeroMemory(buf,Len); if(Len <= BUFSIZE) { retVal = recv(client,buf,sizeof(char) * Len,0); if(retVal == SOCKET_ERROR) { cout<<"Recv Into error: "<<GetLastError()<<endl; cout<<"Fail char*!"<<endl; return false; } } else { int rbufReal = 0, rbufNeed = Len; while (rbufReal < Len) { retVal = recv(client,buf,sizeof(char) * BUFSIZE,0); if(retVal == SOCKET_ERROR) { cout<<"Recv Into error: "<<GetLastError()<<endl; cout<<"Fail char*!"<<endl; return false; } rbufReal += retVal; rbufNeed = Len - rbufReal; } } return true; } bool SockData::recvData(const string rfileRoad) { int length = recvData(); char* buf = new char[BUFSIZE]; ZeroMemory(buf, BUFSIZE); ofstream out(rfileRoad,fstream::out|fstream::binary); if(!out.is_open()) { cout<<"don't create file."<<endl; return false; } int rbufReal = 0, rbufNeed = length; while (rbufReal < length) { if(recvData(buf)) { rbufReal += retVal; rbufNeed = length - rbufReal; out.write(buf,sizeof(char)*retVal); } } out.close(); delete[] buf; return true; }
代码托管:https://github.com/zhanxiage1994/VCplusSocket.git