Scene:
1. When using socket communication, the client or server needs 1-to-many cases, in order to maintain multiple connections, the simple blocking mode is
Can not meet the requirements, so the need for a simple select I/O model is basically able to solve the problem, because its recv and send is not
Returned immediately, so it actually belongs to the blocking mode.
Non-blocking mode requires a call:
Nret = ioctlsocket (S, Fionbio, (unsigned long) &ul);
2. Blocking mode encoding is in fact a risk of suspending the program, because Read,send is likely to cause the program to not get a timely response
Lost data.
3. Socket mode, I/O model these studies understand that the scope of application is a very time-taking thing.
Introduced:
1. There are two modes in socket mode (or socket operating mode), one is blocking mode, and the other is non-blocking mode.
The two models are divided into several I/O models (models). There are 6 I/O model for Winsock, so don't confuse the mode and
Model.
6 medium I/O model: Blocking, select, WSAAsyncSelect, WSAEventSelect, overlapped, and completion port
Refer to "Network Programming for Microsoft Windows 2nd"
2. Berkeley socket Interface (Berkeley socket), winsock1.1 backwards compatible with Berkeley sockets, so porting to other platforms is also more convenient.
Reference reading: Http://zh.wikipedia.org/zh-cn/Berkeley_sockets.
"Network Programming for Microsoft Windows 2nd":
The select model was incorporated into Winsock 1.1 to allow applications that want to avoid blocking on socket calls the C Apability to manage multiple sockets in an organized manner.
English: The Select model is incorporated into Winsock 1.1 to allow applications to avoid socket blocking, which provides an organized way to manage multiple sockets.
Socket_select_client.cpp
Socket_select_client.cpp: Defines the entry point of the console application. #include "stdafx.h" #include <winsock2.h> #include <stdint.h> #include <windows.h> #include < Iostream>using namespace Std; Socket Getnewsocket () {socket server_socket;fd_set fdread,fdwrite;int ret;//Create a socket, and accept a connection Server_socket = socket (af_inet, sock_stream, ipproto_tcp); if (Server_socket = = Invalid_socket) {return invalid_socket;} return server_socket;} int Connecttodevice (SOCKET server_socket,uint16_t port) {struct sockaddr_in server;server.sin_family = af_inet; SERVER.SIN_ADDR.S_ADDR = inet_addr ("127.0.0.1"); server.sin_port = htons (port); int r =:: Connect (Server_socket, ( sockaddr*) &server, sizeof (server)), if (r = = socket_error) {DWORD dwerror =:: WSAGetLastError (); cout << "Connec T error "<< endl;if (dwerror! = wsaewouldblock) {cout <<" dwerror! = wsaewouldblock "<< Endl;closesocke T (server_socket); return invalid_socket;}} cout << "Connect" << endl;reTurn 0;} DWORD WINAPI sendthread (PVOID pvparam) {cout << "sendthread" << Endl; SOCKET s = * (socket*) pvparam;const int klen = 1024;char Buf[klen];int i = 1;while (true) {cout << "I:" << i < ;< Endl;memset (Buf,i,klen); send (s,buf,klen,0); Sleep (+); ++i;} return 0;} void Startclient () {SOCKET s = getnewsocket (); Connecttodevice (s,8083);//1. Start the send thread. DWORD dwThreadID; HANDLE hthread = CreateThread (Null,0,sendthread, (PVOID) &s,0,&dwthreadid); CloseHandle (hthread); Fd_set Fdread;char Buffer[1024];while (True) {Fd_zero (&fdread); Fd_set (S, &fdread); Timeval TV = {1,0};int ret = select (0, &fdread, NULL, NULL, &TV); for (int i = 0; i< ret; ++i) {int readed = 0;//1 . with serverreaded = recv (s,buffer,1024,0); if (readed = = socket_error) {int code = WSAGETLASTERROR (); cout << "code:" < ;< code << Endl;//1.socket has broken break;} else if (readed = = 0) {//If the connection have been gracefully closed,//The return value is zero.break;} ELSE{//1. Reading data cout << "readEd: "<< readed << Endl;}}} Closesocket (s);} int _tmain (int argc, _tchar* argv[]) {wsadata wsa; WSAStartup (Makeword (2,2), &WSA); Startclient (); WSACleanup (); return 0;}
Socket_select_server.cpp
Test_socket_select.cpp: Defines the entry point of the console application. #include "stdafx.h" #include <winsock2.h> #include <windows.h> #include <iostream>using namespace Std;void StartServer () {fd_set fdread,fdwrite; Socket server_socket = socket (af_inet, sock_stream, ipproto_tcp); struct sockaddr_in server;server.sin_family = AF_INET; SERVER.SIN_ADDR.S_ADDR = inet_addr ("127.0.0.1"); int value = 8083;server.sin_port = htons (value); int ret = bind (Server_ sockets, (sockaddr*) &server, sizeof (server)), cout << "binding port ..." << value << Endl; if (ret = = socket_error) {int code = WSAGETLASTERROR (); cout << "ERROR Binding Code:" << code << Endl;clos Esocket (server_socket); return;} RET = Listen (Server_socket, 4); int nSize = sizeof (server); Newconn:socket Client_conn = Accept (Server_socket, (sockaddr*) &server, &nsize); char buf[64];int buf_size = 64; GetSockOpt (Client_conn, sol_socket,so_max_msg_size,buf,&buf_size); if (client_conn = = INVALID_SOCKET) { Closesocket (SErver_socket); return;} cout << "Accept" << endl;const int klen = 512;char Buffer[klen]; ZeroMemory (buffer, Klen), while (true) {Fd_zero (&fdread);//1. Join Fdread, if there are multiple connections, this is also the way to add FDREAD.//2. Getting a client connection actually requires a separate thread to listen to the fetch and join the queue. Fd_set (Client_conn, &fdread);//1.the Select function returns the total number of sockets handles//that is ready and Contained in the fd_set structures,//zero if the time limit expired, or socket_error if an ERROR occurredif (ret = SE Lect (0, &fdread, NULL, NULL, NULL)) = = Socket_error) {closesocket (client_conn); goto Newconn;} for (int i = 0; I <ret; ++i) {//1. This should actually be based on I traversing fdread, such as conns[i], not CLIENT_CONN.//1. You can use vectors to store sockets. Children's shoes have time to write their own. /1.nonzero If S is a member of the set. Otherwise, Zero. if (Fd_isset (Client_conn, &fdread)) {cout << "get Fdread" << endl;int readed = 0;readed = recv (Client_conn, buffer,klen,0); if (readed = = socket_error) {int code = WSAGETLASTERROR (); cout << "code:" << code << Endl; 1.socket has been disconnected CLosesocket (client_conn); goto Newconn;} else if (readed = = 0) {//If the connection have been gracefully closed,//The return value is Zero.closesocket (client_conn) ; goto Newconn;} ELSE{//1. Read data cout << "readed:" << readed << ":" << (int) buffer[0] << endl;//1. Send data Send (Clie nt_conn,buffer,readed,0);}}} Closesocket (Server_socket);} int _tmain (int argc, _tchar* argv[]) {wsadata wsa; WSAStartup (Makeword (2,2), &WSA); StartServer (); WSACleanup (); return 0;}
Output:
[model] of the I/O model under Network programming]_[socket]_[socket blocking mode (blocking)