Server:
#include <iostream> #include <WinSock2.h> #pragma comment(lib,"ws2_32.lib") #define NUM_SEND_CHAR 30 int main() { WSAData wsaData; WSAStartup(MAKEWORD(2,2),&wsaData); SOCKET sktServer=socket(AF_INET,SOCK_STREAM,IPPROTO_TCP); sockaddr_in addrServer; addrServer.sin_family=AF_INET; addrServer.sin_addr.s_addr=inet_addr("127.0.0.1"); addrServer.sin_port=htons(4000); bind(sktServer,(sockaddr*)&addrServer,sizeof(addrServer)); listen(sktServer,5); std::cout<<"Recv Data"<<std::endl; int iErrorCode; while(true) { sockaddr_in addrAccept; int len=sizeof(addrAccept); SOCKET sktAccept=accept(sktServer,(sockaddr*)&addrAccept,&len); if(INVALID_SOCKET==sktAccept) continue; char* pRecvData=new char[NUM_SEND_CHAR]; memset(pRecvData,0,NUM_SEND_CHAR); iErrorCode=recv(sktAccept,pRecvData,NUM_SEND_CHAR,0); /* if(SOCKET_ERROR==iErrorCode) { if( WSAGetLastError()==WSAEWOULDBLOCK ) continue; std::cout<<"Recv failed."<<std::endl; closesocket(sktServer); WSACleanup(); return -1; } */ std::cout<<"Recv Data : "<<pRecvData<<std::endl; delete [] pRecvData; sktAccept=INVALID_SOCKET; } std::cout<<"Over"<<std::endl; getchar(); return 0; }
Client:
#include <iostream> #include <WinSock2.h> #pragma comment(lib,"ws2_32.lib") #define NUM_SEND_CHAR 30 DWORD __stdcall Perform(void* pParam); int identity=1; int main() { WSAData wsaData; int iErrorCode; WSAStartup(MAKEWORD(2,2),&wsaData); SOCKET sktClient=socket(AF_INET,SOCK_STREAM,IPPROTO_TCP); sockaddr_in addrServer; addrServer.sin_family=AF_INET; addrServer.sin_addr.s_addr=inet_addr("127.0.0.1"); addrServer.sin_port=htons(4000); iErrorCode=connect(sktClient,(sockaddr*)&addrServer,sizeof(addrServer)); if(SOCKET_ERROR==iErrorCode) { std::cout<<"Connecting failed."<<std::endl; closesocket(sktClient); WSACleanup(); return -1; } while(true) { char* pSendChar=new char[NUM_SEND_CHAR]; memset(pSendChar,0,NUM_SEND_CHAR); memset(pSendChar,(char)(((int)'0')+identity++),NUM_SEND_CHAR-1); iErrorCode=send(sktClient,pSendChar,NUM_SEND_CHAR,0); /* if(SOCKET_ERROR==iErrorCode) { std::cout<<"Sending failed."<<std::endl; closesocket(sktClient); WSACleanup(); return -1; } */ delete [] pSendChar; std::cout<<"Sending the data..."<<std::endl; } closesocket(sktClient); WSACleanup(); std::cout<<"Over"<<std::endl; getchar(); return 0; }
显示结果:
期望结果 是显示:
1111111111111
2222222222222
3333333333333
。。。
疑惑:为什么只接收了 一次就不能循环下去?
============================
后来修改代码如下:
server: #include <iostream> #include <WinSock2.h> #include <exception> #pragma comment(lib,"ws2_32.lib") #define NUM_SEND_CHAR 30 int main() { WSAData wsaData; WSAStartup(MAKEWORD(2,2),&wsaData); SOCKET sktServer=socket(AF_INET,SOCK_STREAM,IPPROTO_TCP); sockaddr_in addrServer; addrServer.sin_family=AF_INET; addrServer.sin_addr.s_addr=inet_addr("127.0.0.1"); addrServer.sin_port=htons(4000); bind(sktServer,(sockaddr*)&addrServer,sizeof(addrServer)); listen(sktServer,5); std::cout<<"Recv Data"<<std::endl; int iErrorCode; while(true) { try{ sockaddr_in addrAccept; int len=sizeof(addrAccept); SOCKET sktAccept=accept(sktServer,(sockaddr*)&addrAccept,&len); if(INVALID_SOCKET==sktAccept) continue; char* pRecvData=new char[NUM_SEND_CHAR]; memset(pRecvData,0,NUM_SEND_CHAR); iErrorCode=recv(sktAccept,pRecvData,NUM_SEND_CHAR,0); /* if(SOCKET_ERROR==iErrorCode) { if( WSAGetLastError()==WSAEWOULDBLOCK ) continue; std::cout<<"Recv failed."<<std::endl; closesocket(sktServer); WSACleanup(); return -1; } */ std::cout<<"Recv Data : "<<pRecvData<<std::endl; delete [] pRecvData; /* closesocket(sktAccept); Sleep(4000); */ shutdown(sktAccept,2); } catch (...) { std::cout<<"Exception : "<<std::endl; } } std::cout<<"Over"<<std::endl; getchar(); return 0; }
Client:
#include <iostream> #include <WinSock2.h> #pragma comment(lib,"ws2_32.lib") #define NUM_SEND_CHAR 30 DWORD __stdcall Perform(void* pParam); int identity=1; int main() { WSAData wsaData; int iErrorCode; WSAStartup(MAKEWORD(2,2),&wsaData); sockaddr_in addrServer; addrServer.sin_family=AF_INET; addrServer.sin_addr.s_addr=inet_addr("127.0.0.1"); addrServer.sin_port=htons(4000); while(true) {
//移动一下位置 SOCKET sktClient=socket(AF_INET,SOCK_STREAM,IPPROTO_TCP); iErrorCode=connect(sktClient,(sockaddr*)&addrServer,sizeof(addrServer)); if(SOCKET_ERROR==iErrorCode) { continue; } char* pSendChar=new char[NUM_SEND_CHAR]; memset(pSendChar,0,NUM_SEND_CHAR); memset(pSendChar,(char)(((int)'0')+identity++),NUM_SEND_CHAR-1); iErrorCode=send(sktClient,pSendChar,NUM_SEND_CHAR,0); /* if(SOCKET_ERROR==iErrorCode) { std::cout<<"Sending failed."<<std::endl; closesocket(sktClient); WSACleanup(); return -1; } */ delete [] pSendChar; std::cout<<"Sending the data..."<<std::endl; shutdown(sktClient,2); } WSACleanup(); std::cout<<"Over"<<std::endl; getchar(); return 0; }
这样可以见到预期的效果,当然电脑会报警的,呵呵!
你server端accept一个socket后只recv了一次,打印输出后,然后就没有理它,继续accept下一个socket。 也就是说,server端对同一个socket只会调用一次接收,自然只会有一次输出。
要想接收多个输出,应该在对每个个socket开一个循环,在循环中调用recv语句才对呀。
那样是可以的,其实这个代码是用来同时开多个Client的,这样就有两个问题需要解决:
1,client怎样知道自己的socket缓冲区中上次发送的数据已经清空了,可以进行下一次发送?
2,因为client发送数据时,server的 recv是阻塞的。所以server recv时候怎么确保client没有在发送数据?
求助中。。。