Home > Software engineering >  How to select () model to the asynchronous mode
How to select () model to the asynchronous mode

Time:09-20

Due to the use of the select () model can achieve one-to-many TCP communications, so I want to use the select () model to produce a group chat software, the server can receive all messages from the client, and will receive a message to display in the list box, the problem is the select () model can not automatically receives the message, because the select () models are blocked but not asynchronous,
I watched a console interface from the book of the server-side program, because after the console application receives the message will automatically pop up, so there is no problem, but I want to change it to MFC version of the program, the above problems, how to let any client sent message, the server will automatically displays a message in the list box, the following is my program, how to modify the good,

 void CSelwinsDlg: : OnCreate () 
{
/* * * initializes the winsock2. DLL/* * *
WSADATA WSADATA;
WORD wVersionRequested=MAKEWORD (2, 2);//generated version 2.2
If (WSAStartup (wVersionRequested, & amp; WsaData)!=0)
{
C_recvbuf. AddString (" loading winsock DLL failed! \n");

}
/* * * * * */create socket
If ((sock_server=socket (AF_INET SOCK_STREAM, 0)) & lt; 0)
{
C_recvbuf. AddString (" failed to create a socket! \n");
WSACleanup ();

}
/* * * to binding local address * * */
Int addr_len=sizeof (struct sockaddr_in);
Memset ((void *) & amp; Addr, 0, addr_len);
Addr. Sin_family=AF_INET;
Addr. Sin_port=htons (PORT);
Addr. Sin_addr. S_addr=htonl (INADDR_ANY);//allow the socket to use the machine any IP
/* * * to listening socket binding address * * */
If (bind (sock_server, (struct sockaddr *) & amp; Addr, sizeof (addr))!=0)
{
C_recvbuf. AddString (" address binding failed! \n");
Closesocket (sock_server);
WSACleanup ();

}
/* * * will socket set to listening state * * * */
If (listen (sock_server, 0)!=0)
{
C_recvbuf. AddString (" listen function call failed! \n");
Closesocket (sock_server);
WSACleanup ();

}
The else
C_recvbuf. AddString (" listenning... \n");
FD_ZERO (& amp; Fdsock);//initialize fdsock
FD_SET (sock_server, & amp; Fdsock);//add the listening socket to socket set fdsock
/* * * cycle: receive connection requests and send and receive data * * */
While (true)
{
FD_ZERO (& amp; Fdread);//initialize fdread
Fdread=fdsock;//will all the socket in the fdsock added to the fdread
If (select (0, & amp; Fdread, NULL, NULL, NULL) & gt; 0)
{
for(int i=0; i{
If (FD_ISSET (fdsock fd_array [I], & amp; Fdread))
{
If (fdsock fd_array [I]==sock_server)
{//a client connection request arrives, receives the connection request
Newsock=accept (sock_server, (struct sockaddr *) & amp; Client_addr, & amp; Addr_len);
If (newsock==INVALID_SOCKET)
{//accept error to terminate all communication, the end of the program
C_recvbuf. AddString (" the accept function call failed! \n");
for(int j=0; JClosesocket (fdsock fd_array [j]);//close all socket
WSACleanup ();//logout WinSock dynamic link library

}
The else
{
C_recvbuf. AddString (inet_ntoa (client_addr sin_addr));
Send (newsock, MSG, sizeof (MSG), 0).//send a message
FD_SET (newsock, & amp; Fdsock);//to add new socket fdsock
}
}
The else
{//a client data, receive data
Memset ((void *) msgbuffer, 0, sizeof (msgbuffer));//buffer reset
Int size=recv (fdsock fd_array [I], msgbuffer, sizeof (msgbuffer), 0).
If (size
0)//receiving informationC_recvbuf. AddString (receive information failed! "" );
Else if (size==0)
C_recvbuf. AddString (someone has closed!" \n");
The else
{//show received information
Getpeername (fdsock fd_array [I], (struct sockaddr *) & amp; Client_addr, & amp; Addr_len);//get the other IP address
C_recvbuf. AddString (msgbuffer);
}
Closesocket (fdsock fd_array [I]);//close the socket
FD_CLR (fdsock fd_array [I], & amp; Fdsock);//remove the socket closed
}
}
}
}
The else
{
C_recvbuf. AddString (" the Select call failed!" );
break;//terminate the loop exit program
}
}
}

CodePudding user response:

Open threads, specially the select recv news,
You this OnCreate is completely blocked, while dead circulation, open a thread, of course, calls OnCreate, so BuKa main interface

CodePudding user response:

the socket of the select function in detail

CodePudding user response:

reference 1st floor smwhotjay response:
open threads, specifically select recv,
You are blocking the OnCreate completely, while dead circulation, open a thread, of course, calls OnCreate, so BuKa Lord interface


Not to say that the Select model can implement the one-to-many communication, is a single thread can't realize my above procedures,
I tried again, the program can receive the above client's news, but can only receive the client sent the first message, then the client can display "normally closed connection", should be on the server side Select model triggered the client FD_CLOSE event, I see the Internet said the Select model will send zero bytes of heartbeat packets to the client, is for this reason,

And the server starts, has been in the blocking state, on the server side I add ioctlsocket (newsock FIONBIO, & amp; NonBlock); Still is the blocking state,

And the above procedure can only use AfxMessageBox (msgbuffer); Receives the message, but they could not use c_recvbuf. AddString (msgbuffer); The message is added to the list box, do not know why,

CodePudding user response:

Your OnCreate calls in the main thread. The UI

CodePudding user response:

Your OnCreate calls in the main thread. The UI is blocked so receive less than, can only to open a thread

CodePudding user response:

OnCreate is a button event, have an ID is IDC_Create button,

CodePudding user response:

The idea that you are wrong. "the select () model are blocked but not asynchronous"
Non-blocking, that is, in order to implement the asynchronous.

Only you and your requirements of the asynchronous is different, you need to recv after receiving the message, the message content posted to the main thread, and then added to the message box.
There are several kinds of solution:
1. After recv the message content directly to sent via PostMessage UI thread (your main window), and then put the message content parsing, added to the message box.
2. After recv, added to a message queue. The other start a thread, responsible for a message from the message queue, and then added to the message box

CodePudding user response:

Basic understand, if you want to write the Windows interface program must Select model using multithreading, can the program interface thread plug, otherwise Select is blocking model, non-blocking asynchronous model is not necessarily, but the asynchronous model must be blocked,
  • Related