# Include <winsock2.h>
# Include <stdio. h>
# Include <windows. h>
# Pragma comment (Lib, "ws2_32.lib ")
Bool insertsock (socket * psock, socket sock)
{
For (INT nindex = 0; nindex <fd_setsize-1; nindex ++)
{
If (psock [nindex] = invalid_socket)
{
Psock [nindex] = sock;
Break;
}
}
If (nindex = fd_setsize-1)
Return false;
Return true;
}
Int main (INT argc, char * argv [])
{
Wsadata;
Word sockversion = makeword (2, 0 );
Wsastartup (sockversion, & wsadata );
Socket clientsockarray [fd_setsize-1];
Socket S = socket (af_inet, sock_stream, ipproto_tcp );
If (S = invalid_socket)
{
Printf ("failed socket ()/n ");
Wsacleanup ();
Return 0;
}
Sockaddr_in sin;
Sin. sin_family = af_inet;
Sin. sin_port = htons (8888 );
Sin. sin_addr.s_un.s_addr = inaddr_any;
If (BIND (S, (lpsockaddr) & sin, sizeof (SIN) = socket_error)
{
Printf ("failed BIND () % d/N", getlasterror ());
Wsacleanup ();
Return 0;
}
If (Listen (S, 63) = socket_error)
{
Printf ("failed listen ()/n ");
Wsacleanup ();
Return 0;
}
For (INT I = 0; I <64; I ++)
{
Clientsockarray [I] = invalid_socket;
}
Sockaddr_in remoteaddr;
Int naddrlen = sizeof (remoteaddr );
// Char sztext [] = "Hello world! ";
Fd_set FD;
Fd_zero (& FD );
Timeval TV = {30, 0 };
Fd_set (S, & FD );
Printf ("Server start: % d/N", getlasterror ());
Int num = 0;
While (true)
{
Int nresult;
Nresult = select (0, & FD, null, null, & TV );
If (nresult = socket_error)
{
Printf ("select failed/N ");
Continue;
}
/*
If (nresult> 0)
{
Printf ("dddddddddd/N ");
}
*/
If (fd_isset (S, & FD ))
{
Socket Client;
Client = accept (S, (sockaddr *) & remoteaddr, & naddrlen );
If (client = invalid_socket)
{
Printf ("client connect fail % d", getlasterror ());
Continue;
}
If (! Insertsock (clientsockarray, client ))
{
Printf ("too many sockets × ó ''socket/N ");
Closesocket (client );
Continue;
}
Fd_set (client, & FD );
}
// Öð omö' ¦ fií'ó óú' ý ö ö×' ì µ µäì × ½ óxö
Nresult = select (0, & FD, null, null, & TV );
If (nresult = socket_error)
{
Printf ("select failed/N ");
Continue;
}
For (INT nindex = 0; nindex <= fd_setsize-1; nindex ++)
{
If (fd_isset (clientsockarray [nindex], & FD ))
{
// Printf ("AAAA/N ");
Char buffer [256];
Int nret = Recv (clientsockarray [nindex], buffer, sizeof (buffer), 0 );
If (nret = 0 | nret = socket_error)
{
Closesocket (clientsockarray [nindex]);
Clientsockarray [nindex] = invalid_socket;
Continue; // ¼ ì ð ø '**************************************
}
// When «ó ê ü μ µ äê ö ø?
// Char buffer [256];
// Recv (clientsockarry [nindex], buffer, 256 );
Printf ("has Recv data from socket % d: % s", I, buffer );
Printf ("Num: % d/N", ++ num );
}
}
}
Closesocket (s );
Wsacleanup ();
Return 0;
}
An example is provided ,,
The following code is a multi-connection application established in select, which is an I/O model. Can work normally.
But there are some problems. After accepting 2 or more connections, the data sent by these connections is always received, which is unstable.
For example;
After accepting three connections.
1. Connect to send data 11111.
Display 11111.
2 connection sends 22222.
Show 22222
Run one task.
3. The connection sends 33333 messages.
Display is
3
3
3
3
3. After 5 rounds, the data is received separately.
I don't understand why the program becomes unstable?
Why does one piece of data always count, one byte or one byte?
Why does the message always receive null messages?
Where is it not handled?
The Code is as follows:
// Select I/O model
# Include <stdio. h>
# Include <winsock2.h>
# Pragma comment (Lib, "ws2_32 ")
Int ret;
Int main ()
{
Ushort nport = 12345; // The port number that the server listens
Wsadata;
If (wsastartup (0x0202, & wsadata )! = 0)
{
Printf ("wsastartup error! /N ");
Getchar ();
Return 0;
}
// Create a listening set of characters
Socket slisten = socket (af_inet, sock_stream, ipproto_tcp );
Sockaddr_in sin;
Sin. sin_family = af_inet;
Sin. sin_port = htons (nport );
Sin. sin_addr.s_un.s_addr = inaddr_any;
// Bind the character set to the Local Machine
If (BIND (slisten, (sockaddr *) & sin, sizeof (SIN) = socket_error)
{
Printf ("failed BIND ()/n ");
Return 0;
}
If (Listen (slisten, 5 ))
{
Printf ("Listen error! /N ");
Getchar ();
Return 0;
}
// --------------------------------------------------- It seems that the setting of this mode is necessary.
Ulong nonblock = 1;
If (ioctlsocket (slisten, fionbio, (u_long *) & nonblock) = socket_error)
{
Printf ("ioctlsocket () failed with error % d/N", wsagetlasterror ());
Getchar ();
Return 0;
}
//----------------------------------------------------
// Select model processing process
// 1) initialize a set of characters fdsocket and add a listening set of character handles to this set.
Fd_set fdsocket; // a collection of all applicable sets of Characters
Fd_zero (& fdsocket );
Fd_set (slisten, & fdsocket );
While (true)
{
Ret = printf ("/n big while -----------------------! /N ");
// 2) pass a copy of The fdsocket set fdread to the select function,
// When an event occurs, the Select function removes the character handle that has no pending I/O operations in the fdread set and returns the result.
Fd_set fdread = fdsocket;
Int nret = select (0, & fdread, null );
If (nret> 0)
{
// 3) Compare the fdread set processed by the SELECT statement with the fdsocket set,
// Determine which sets of knots are pending I/O and further process these I/O.
For (INT I = 0; I <(INT) fdsocket. fd_count; I ++)
{
Ret = printf ("/n big! /N ");
If (fd_isset (fdsocket. fd_array [I], & fdread ))
{
If (fdsocket. fd_array [I] = slisten) // (1) Listen to the set of characters to receive new connections
{
If (fdsocket. fd_count <fd_setsize)
{
Sockaddr_in addrremote;
Int naddrlen = sizeof (addrremote );
Socket snew =: accept (slisten, (sockaddr *) & addrremote, & naddrlen );
Fd_set (snew, & fdsocket );
Printf ("received connection (% s)/n",: inet_ntoa (addrremote. sin_addr ));
}
Else
{
Printf ("too much connections! /N ");
Continue;
}
}
Else
{
Char sztext [256];
Int nrecv =: Recv (fdsocket. fd_array [I], sztext, sizeof (sztext), 0 );
If (nrecv> 0) // (2) readable
{
Sztext [nrecv] = '/0 ';
Printf ("received data: % s/n", sztext );
}
Else // (3) the connection is closed, restarted, or interrupted.
{
: Closesocket (fdsocket. fd_array [I]);
Fd_clr (fdsocket. fd_array [I], & fdsocket );
}
}
}
}
}
Else
{
Printf ("failed select ()/n ");
Break;
}
}
Return 0;
}