Windows socket programming TCP Example 4 (wsaeventselect)

Source: Internet
Author: User
Winsock provides another useful asynchronous event notification I/O model-wsaeventselect model. Similar to the wsaasyncselect model, this model allows applications to receive event-based network notifications on one or more sockets. It is similar to the wsaasyncselect model because it also receives network events of the fd_xxx type. However, it does not rely on the message-driven mechanism of windows, but is notified through the event object handle. The following example shows how to implement the same function as the previous two articles (one & Two & Three): the client connects to the server and sends data to the server. The server receives and outputs the data sent from the client. The server still processes multi-client connections in a single thread.

Server. cpp -----------------------------

# Include <iostream> # include <winsock2.h> # include <windows. h> using namespace STD; # pragma comment (Lib, "ws2_32.lib ") # define port_no 6000 # define backlog 10 // record the socket and corresponding event array and array size wsaeventeventarray [wsa_maximum_wait_events] = {0}; socketsockarray [events] = {0 }; int neventtotal = 0; // empty array element with the serial number nindex: socket and eventvoid clearindex (INT nindex); int main (INT argc, char * argv []) {wsadata WSA Data; int ret; Word wversionrequested = makeword (2, 2); socket socksrv; sockaddr_in addrsrv; // 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; // create the wsaevent corresponding to socksrv and add it to the array ---- -- Wsaevent wsaevt = require (); wsaeventselect (socksrv, wsaevt, fd_accept | fd_close); eventarray [neventtotal] = wsaevt; sockarray [neventtotal] = socksrv; neventtotal ++; // socket Event Response ------ while (1) {int nindex = wsawaitformultipleevents (neventtotal, eventarray, false, wsa_infinite, false); If (wsa_wait_failed = nindex) {cout <"wsawaitformultipleevents failed:" <wsagetlasterror () <Endl; break;} Nindex = nindex-events; socket sock = sockarray [nindex]; wsaevent wsaevt = eventarray [nindex]; wsanetworkevents networkevts; dependencies (sock, wsaevt, & networkevts); If (networkevts. lnetworkevents & fd_accept) // --- fd_accept {If (networkevts. ierrorcode [fd_accept_bit] = 0) {sockaddr_in addrclient; int Len = sizeof (sockaddr); socket sockconn = accept (sock, (sockaddr *) & addrclient, & Len ); If (invalid_socket = sockconn) {cout <"accept () failed:" <wsagetlasterror () <Endl; continue;} cout <"receives a new connection: "<inet_ntoa (addrclient. sin_addr) <Endl; If (neventtotal> = wsa_maximum_wait_events) {cout <"too has connections! "<Endl; closesocket (sockconn); continue;} wsaevent sockconnevt = require (); wsaeventselect (sockconn, sockconnevt, fd_read | fd_close | fd_write); eventarray [neventtotal] = sockconnevt VT; sockarray [neventtotal] = sockconn; neventtotal ++ ;}} else if (networkevts. lnetworkevents & fd_read) // --- fd_read {If (networkevts. ierrorcode [fd_read_bit] = 0) {char recvbuffer [max_path] = {0}; int ret = Recv (sock, recvbuffer, sizeof (recvbuffer), 0 ); if (ret = 0) {cout <"connection has been gracefully closed. "<Endl; closesocket (sock); closehandle (wsaevt); clearindex (nindex); continue;} else if (ret = socket_error) {cout <"connection has been closed ungracefully. "<Endl; closesocket (sock); closehandle (wsaevt); clearindex (nindex); continue;} cout <" receive data from client: "<recvbuffer <Endl ;}} else if (networkevts. lnetworkevents & fd_close) // --- fd_close {If (networkevts. ierrorcode [fd_close_bit] = 0) {cout <"connection has been gracefully closed. "<Endl;} else {cout <" connection has been closed ungracefully. "<Endl;} closesocket (sock); closehandle (wsaevt); clearindex (nindex);} else if (networkevts. lnetworkevents & fd_write) // --- fd_write {}} // clear the resource ------ for (INT I = 0; I <neventtotal; ++ I) {closesocket (sockarray [I]); closehandle (eventarray [I]);} wsacleanup (); cout <"exit... "<Endl; return 0;} // empty array elements with the serial number nindex: socket and eventvoid clearindex (INT nindex) {// parameter validity check 0 = <nindex <= WSA_MAXIMUM_WAIT_EVENTS-1if (nindex <0 | nindex> = wsa_maximum_wait_events | nindex> = neventtotal) return; // clear the last element, 0 if (nindex = neventtotal-1) {eventarray [nindex] = 0; sockarray [nindex] = 0; neventtotal --; return ;} // forward (INT I = nindex; I <= nEventTotal-2; ++ I) {eventarray [I] = eventarray [I + 1]; sockarray [I] = sockarray [I + 1]; neventtotal --;}}

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 ;}

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.