今天抽空看了一些简单的东西,主要是对服务器server和客户端client的简单实现。
面向连接的server和client,其工作流程如下图所示:
服务器和客户端将按照这个流程就行开发。。(个人觉得:通过这个流程图,Server应该要先于Client启动,不然Client的connect函数的执行就会出错啦,不知道我的个人感觉对不对,后面试试就知道了。。O(∩_∩)O~)
注意:上图的Server和Client的工作流程是基于面向有连接通信的工作流程,如果是无连接的通信,则不必调用listen和accept。 在无连接的通信中,Server调用recvfrom函数来接收消息
在编写服务器和客户端之前,需要对TCP状态有所了解。。在server和client通信之间,二者都是通过发送/接收不同的信号来改变自己的状态,其tcp状态转换图如下:
了解了二者的开发流程,就可以通过接口来具体实现。
简单的server代码实现:
1 #include"winsock2.h" 2 #include<iostream> 3 using namespace std; 4 //This line is very important 5 6 #pragma comment(lib,"ws2_32.lib") 7 int main() 8 { 9 WSADATA wsaData; 10 SOCKET ListeningSocket; 11 SOCKET NewConnection; 12 SOCKADDR_IN ServerAddr; 13 SOCKADDR_IN ClientAddr; 14 int ClientAddrLen; 15 int Port = 5150; 16 int Ret; 17 char DataBuffer[1024]; 18 19 if ((Ret = WSAStartup(MAKEWORD(2,2), &wsaData)) != 0) 20 { 21 cout<<"WSAStartup failed with error "<<Ret<<endl; 22 //here no WSACleanup,because we do not create anything; 23 return -1; 24 } 25 26 // Create a new socket to listening for client connections. 27 ListeningSocket = socket(AF_INET,SOCK_STREAM,IPPROTO_TCP); 28 if ( INVALID_SOCKET == ListeningSocket) 29 { 30 cout<<"Socket failed with error "<<WSAGetLastError()<<endl; 31 WSACleanup(); 32 return -1; 33 } 34 35 ServerAddr.sin_family = AF_INET; 36 ServerAddr.sin_addr.s_addr = htonl(INADDR_ANY); 37 ServerAddr.sin_port = htons(Port); 38 39 //to bind 40 if (bind(ListeningSocket, (SOCKADDR *)&ServerAddr, sizeof(ServerAddr)) == SOCKET_ERROR) 41 { 42 cout<<"Binding failed with error "<<WSAGetLastError()<<endl; 43 closesocket(ListeningSocket); 44 WSACleanup(); 45 return -1; 46 } 47 48 // Listen for client connections. We used a backlog of 5 which is 49 // normal for many applications. 50 51 if (listen(ListeningSocket,5) == SOCKET_ERROR) 52 { 53 cout<<"Listen failed with error "<<WSAGetLastError()<<endl; 54 closesocket(ListeningSocket); 55 WSACleanup(); 56 return -1; 57 } 58 59 cout<<"** We are waiting for a connection on port "<<Port<<"**"<<endl; 60 61 //accep a connection when one arrives 62 63 NewConnection = accept(ListeningSocket,(SOCKADDR*)&ClientAddr,&ClientAddrLen); 64 if (INVALID_SOCKET == NewConnection) 65 { 66 cout<<"Accept failed with error "<<WSAGetLastError()<<endl; 67 closesocket(ListeningSocket); 68 WSACleanup(); 69 return -1; 70 } 71 72 cout<<"** We successfully got a connection from "<<inet_ntoa(ClientAddr.sin_addr) 73 <<":port "<<ntohs(ClientAddr.sin_port)<<"!!**"<<endl; 74 75 closesocket(ListeningSocket); 76 cout<<"** We are waiting for data...**\n"; 77 78 Ret = recv(NewConnection,DataBuffer,sizeof(DataBuffer),0); 79 if (SOCKET_ERROR == Ret) 80 { 81 cout<<"Recv failed with error "<<WSAGetLastError()<<endl; 82 closesocket(NewConnection); 83 WSACleanup(); 84 return -1; 85 } 86 87 cout<<"**We have successfully recieve "<<Ret<<" Byte(s) data!**\n"; 88 89 cout<<"**We are going to close the client connection...**\n"; 90 91 closesocket(NewConnection); 92 WSACleanup(); 93 94 return 0; 95 }