With the select model, you can connect multiple clients without creating multiple threads for processing, that is, single-thread processing. Example: the client sends data to the server, and the server receives and outputs the data.
Server. cpp
# Include <iostream> # include <windows. h> using namespace STD; # pragma comment (Lib, "ws2_32.lib") # define port_no 6000 # define backlog 10int main (INT argc, char * argv []) {wsadata; int ret; Word wversionrequested = makeword (2, 2); socket socksrv; sockaddr_in addrsrv, addrclient; handle hthread = NULL; // initialize Windows Socket ------ ret = wsastartup (wversionrequested, & wsadata); If (Ret! = 0) {cout <"wsastartup () failed:" <wsagetlasterror () <Endl; Return-1 ;}// create socket ------ socksrv = socket (af_inet, sock_stream, 0); If (invalid_socket = socksrv) {cout <"socket () failed:" <wsagetlasterror () <Endl; wsacleanup (); return-1;} addrsrv. sin_addr.s_un.s_addr = htonl (inaddr_any); addrsrv. sin_family = af_inet; addrsrv. sin_port = htons (port_no); // bind socket ------ ret = BIND (socksrv, (S Ockaddr *) & addrsrv, sizeof (sockaddr); If (socket_error = RET) {cout <"BIND () failed:" <wsagetlasterror () <Endl; closesocket (socksrv); wsacleanup (); Return-1;} // listen ------ ret = listen (socksrv, backlog); If (socket_error = RET) {cout <"Listen () failed:" <wsagetlasterror () <Endl; closesocket (socksrv); wsacleanup (); Return-1 ;} cout <"server started ...... "<Endl; // select ------ // single-threaded Multi-client processing fd_se T fdsocketall; // record all socketfd_zero (& fdsocketall); fd_set (socksrv, & fdsocketall); While (1) {fd_set fdread = fdsocketall; ret = select (0, & fdread, null, null, null); If (0 = RET) // timeout. Since timeout is set to null, all cout statements without timeout are {cout <"over time... "<Endl; continue;} else if (Ret> 0) // OK {# pragma regionfor (INT I = 0; I <(INT) fdread. fd_count; ++ I) {socket sock = fdread. fd_array [I]; If (sock = socksrv) // The Listener socket accepts the new connection {int Len = sizeof (sockaddr); socket sockconn = accept (socksrv, (sockaddr *) & addrclient, & Len); If (invalid_socket = sockconn) {cout <"accept () failed: "<wsagetlasterror () <Endl; break;} cout <" New Connection Received: "<: inet_ntoa (addrclient. sin_addr) <Endl; If (fdsocketall. fd_count <fd_setsize) {fd_set (sockconn, & fdsocketall);} else {cout <"too much connections! "<Endl; closesocket (sockconn) ;}} else // you can read {char recvbuffer [max_path] ={ 0}; ret = Recv (sock, recvbuffer, sizeof (recvbuffer), 0); If (ret = 0) {cout <"connection has been gracefully closed. "<Endl; fd_clr (sock, & fdsocketall); closesocket (sock); continue;} else if (ret = socket_error) {cout <" connection has been closed ungracefully. "<Endl; fd_clr (sock, & fdsocketall); closesocket (sock); continue;} cout <" receive data from client: "<recvbuffer <Endl ;}} # pragma endregion} else // error {cout <"select () failed:" <wsagetlasterror () <Endl; break ;}} // clear the resource ------ for (INT I = 0; I <(INT) fdsocketall. fd_count; ++ I) {closesocket (fdsocketall. fd_array [I]);} wsacleanup (); cout <"exit... "<Endl; return 0 ;}
Client. cpp
# Include <iostream> # include <windows. h> using namespace STD; # pragma comment (Lib, "ws2_32.lib") # define port_no 6000 # define srv_ip_addr "127.0.0.1" int main (INT argc, char * argv []) {int ret; wsadata; Word wversionrequested = makeword (2, 2); socket sockclient; sockaddr_in addrsrv; // initialize Windows Socket ------ ret = wsastartup (wversionrequested, & wsadata ); if (Ret! = 0) {cout <"wsastartup () failed:" <wsagetlasterror () <Endl; Return-1 ;}// create socket ------ sockclient = socket (af_inet, sock_stream, 0); If (invalid_socket = sockclient) {cout <"socket () failed:" <wsagetlasterror () <Endl; wsacleanup (); return-1;} addrsrv. sin_addr.s_un.s_addr = inet_addr (srv_ip_addr); addrsrv. sin_family = af_inet; addrsrv. sin_port = htons (port_no); // connection ------ ret = connect (sockclient, (sockaddr *) & addrsrv, sizeof (sockaddr); If (socket_error = RET) {cout <"Connect () failed:" <wsagetlasterror () <Endl; closesocket (sockclient); wsacleanup (); Return-1 ;} else {cout <"Connect () successfully. "<Endl;} // send data ------ char sendbuf [max_path] = {0}; while (1) {cin. getline (sendbuf, sizeof (sendbuf); If (strcmp (sendbuf, "exit") = 0) {break;} ret = Send (sockclient, sendbuf, strlen (sendbuf) + 1, 0); If (socket_error = RET) {cout <"Send () failed:" <wsagetlasterror () <Endl; closesocket (sockclient ); wsacleanup (); Return-1 ;}// clear resources ------- closesocket (sockclient); wsacleanup (); cout <"exit... "<Endl; return 0 ;}
The slice is as follows: