listen() problem
-
I am driven to the wall. Can anyone help me? I have a server and a client both use TCP/IP socket. The server runs Vxworks while the client runs Windows 2000. the requrirement is that the server can have one client only at a time, so when I initialize the server socket, I say: nRet = listen(ListenSocket, 1); But still, when I run two clients to test it, both can connect()!!! And when I check the messages received by the server,
if ( FD_ISSET(ListenSocket, &ReadSet) && ClientSocket == 0)
HandleNewConnection();
else
logMsg("don't accept\n", 1, 2, 3, 4, 5, 6);I will see that: after the first client successfully connected to the server (ClientSocket != 0 then), I let the second client try to connect to the server. The client will tell me its connect() okay, while the server will say "don't accept\n" all the time until the second client close the connection. What's the use of the MAX_CONNECTION = 1 in my listen() then?? Or if I over look something? any help is highly appreciated!
-
I am driven to the wall. Can anyone help me? I have a server and a client both use TCP/IP socket. The server runs Vxworks while the client runs Windows 2000. the requrirement is that the server can have one client only at a time, so when I initialize the server socket, I say: nRet = listen(ListenSocket, 1); But still, when I run two clients to test it, both can connect()!!! And when I check the messages received by the server,
if ( FD_ISSET(ListenSocket, &ReadSet) && ClientSocket == 0)
HandleNewConnection();
else
logMsg("don't accept\n", 1, 2, 3, 4, 5, 6);I will see that: after the first client successfully connected to the server (ClientSocket != 0 then), I let the second client try to connect to the server. The client will tell me its connect() okay, while the server will say "don't accept\n" all the time until the second client close the connection. What's the use of the MAX_CONNECTION = 1 in my listen() then?? Or if I over look something? any help is highly appreciated!
I have come across this before. First off, I beleive the parameter to listen() is the queue size, so it is valid to be handling 1 call and having one in the queue. Is there any reason you can only have one client? Typical pattern would be to have a server thread for each client. One way I have seen your problem solved is to close the accepting socket straight after the first call to accept. The 2nd client will the get a connection refused error. When you server has finished with the 1st client, it can then re-open the accepting socket. HTH Rob.
-
I have come across this before. First off, I beleive the parameter to listen() is the queue size, so it is valid to be handling 1 call and having one in the queue. Is there any reason you can only have one client? Typical pattern would be to have a server thread for each client. One way I have seen your problem solved is to close the accepting socket straight after the first call to accept. The 2nd client will the get a connection refused error. When you server has finished with the 1st client, it can then re-open the accepting socket. HTH Rob.
Thank you, Bob, (why your signature is Rob though? :confused: ) I tried to shutdown and close the new connection right after accept(). But the client will not receive any feedback from its connect(). But it couldn't send or receive anything either, since there is no connectin at all. Only he (client) doesn't know it. Maybe I should implement some software handshake here to confirm the connection? But there should be some implemented method I could use.. The reason I want only one connection is that the server is running a real-time application, and it should not be disturbed by too many clients, afraid that it would slow down the server's performance. After all, the client's functionality is to record down the server's status for off-line analysis, so one client is enough. I did a version which can accept up to 10 connection, but my collegue said it's a waste of effort.:(
-
Thank you, Bob, (why your signature is Rob though? :confused: ) I tried to shutdown and close the new connection right after accept(). But the client will not receive any feedback from its connect(). But it couldn't send or receive anything either, since there is no connectin at all. Only he (client) doesn't know it. Maybe I should implement some software handshake here to confirm the connection? But there should be some implemented method I could use.. The reason I want only one connection is that the server is running a real-time application, and it should not be disturbed by too many clients, afraid that it would slow down the server's performance. After all, the client's functionality is to record down the server's status for off-line analysis, so one client is enough. I did a version which can accept up to 10 connection, but my collegue said it's a waste of effort.:(
You need to close the accepting socket. eg pseudocode... SOCKET s1 = socket() SOCKET s2 = accept(s1,...) // Now client one is connected to s2 closesocket(s1) // Now no more clients can connect // you need to re-open s1 should the s2 connection fail for any reason. Bob/Rob are both short forms of Robert. At work I am Bob, at Home Rob. I get confused as well sometimes!!
-
You need to close the accepting socket. eg pseudocode... SOCKET s1 = socket() SOCKET s2 = accept(s1,...) // Now client one is connected to s2 closesocket(s1) // Now no more clients can connect // you need to re-open s1 should the s2 connection fail for any reason. Bob/Rob are both short forms of Robert. At work I am Bob, at Home Rob. I get confused as well sometimes!!
Bob Groves wrote: Bob/Rob are both short forms of Robert. I see. there are so many short forms of English name. Yeah, I did the same thing as you suggested. The code is :
SOCKET listenSocket;
listen(listenSocket, 1);while(1)
{
BuildSelectList();
select(HighSocket+1, &ReadSet, NULL, NULL, &timeout);
if ( FD_ISSET(ListenSocket, &ReadSet) )
HandleNewConnection();
else if ( FD_ISSET(ClientSocket, &ReadSet) )
ReadSocket(ClientSocket);
}in HandleNewConnection():
int newSd;
if ( ClientSocket != 0 )
{
newSd = accept(ListenSocket, NULL, NULL);
shutdown(newSd, 2);
close(newSd);
return;
}although I closed the second connection, the client running on Windows 2000 didn't receive any error message from its call of connect(). what should I do?
-
Bob Groves wrote: Bob/Rob are both short forms of Robert. I see. there are so many short forms of English name. Yeah, I did the same thing as you suggested. The code is :
SOCKET listenSocket;
listen(listenSocket, 1);while(1)
{
BuildSelectList();
select(HighSocket+1, &ReadSet, NULL, NULL, &timeout);
if ( FD_ISSET(ListenSocket, &ReadSet) )
HandleNewConnection();
else if ( FD_ISSET(ClientSocket, &ReadSet) )
ReadSocket(ClientSocket);
}in HandleNewConnection():
int newSd;
if ( ClientSocket != 0 )
{
newSd = accept(ListenSocket, NULL, NULL);
shutdown(newSd, 2);
close(newSd);
return;
}although I closed the second connection, the client running on Windows 2000 didn't receive any error message from its call of connect(). what should I do?
I've never used the FD_??? macros, but I just tried the following in the 10 minutes before I went home, and it works OK. I tested it by running "telnet 127.0.0.1 1001" from the DOS prompt twice. The 1st connects, the 2nd doesn't. I hope it works for you too. Gotta run now..... Bob. #include void StartupWinSock() { WORD wVersionRequested; WSADATA wsaData; int err; wVersionRequested = MAKEWORD(2, 0); err = ::WSAStartup(wVersionRequested, &wsaData); } void CSimplesockDlg::OnButton1() { StartupWinSock(); SOCKET s1 = socket(PF_INET, SOCK_STREAM, 0); if (s1 == INVALID_SOCKET) { AfxMessageBox("error creating socket"); return; } struct sockaddr_in serv_addr; memset((char *)&serv_addr, 0, sizeof(serv_addr)); serv_addr.sin_family = AF_INET; serv_addr.sin_addr.s_addr = htonl(INADDR_ANY); serv_addr.sin_port = htons(1001); if (bind(s1, (struct sockaddr*)&serv_addr, sizeof(serv_addr)) < 0) { AfxMessageBox("error binding socket"); return; } if (listen(s1, 1) == SOCKET_ERROR) { AfxMessageBox("error listening on socket"); return; } SOCKET s2 = accept(s1, 0, 0); if (s2 == INVALID_SOCKET) { if (WSAGetLastError() != WSAEWOULDBLOCK) { AfxMessageBox("error accepting socket"); return; } } closesocket(s1); // DO stuff with s2 // No new clients should be able to connect // The Sleep is just so that my simple server does not immediately close down, in real life, you would do you code here. Sleep(60000); }
-
I've never used the FD_??? macros, but I just tried the following in the 10 minutes before I went home, and it works OK. I tested it by running "telnet 127.0.0.1 1001" from the DOS prompt twice. The 1st connects, the 2nd doesn't. I hope it works for you too. Gotta run now..... Bob. #include void StartupWinSock() { WORD wVersionRequested; WSADATA wsaData; int err; wVersionRequested = MAKEWORD(2, 0); err = ::WSAStartup(wVersionRequested, &wsaData); } void CSimplesockDlg::OnButton1() { StartupWinSock(); SOCKET s1 = socket(PF_INET, SOCK_STREAM, 0); if (s1 == INVALID_SOCKET) { AfxMessageBox("error creating socket"); return; } struct sockaddr_in serv_addr; memset((char *)&serv_addr, 0, sizeof(serv_addr)); serv_addr.sin_family = AF_INET; serv_addr.sin_addr.s_addr = htonl(INADDR_ANY); serv_addr.sin_port = htons(1001); if (bind(s1, (struct sockaddr*)&serv_addr, sizeof(serv_addr)) < 0) { AfxMessageBox("error binding socket"); return; } if (listen(s1, 1) == SOCKET_ERROR) { AfxMessageBox("error listening on socket"); return; } SOCKET s2 = accept(s1, 0, 0); if (s2 == INVALID_SOCKET) { if (WSAGetLastError() != WSAEWOULDBLOCK) { AfxMessageBox("error accepting socket"); return; } } closesocket(s1); // DO stuff with s2 // No new clients should be able to connect // The Sleep is just so that my simple server does not immediately close down, in real life, you would do you code here. Sleep(60000); }
-
I tried this. But what would you do after the connection between server and the first client drop? How do you make s1 listen again? Would it be a must to go through the cycle of socket, bind, listen? TIA!
Yes, you would have to go through that cycle. Have a look at MFC'c CSocket, or wrap up the code in your own class to make this easier. Regards, Bob.
-
Yes, you would have to go through that cycle. Have a look at MFC'c CSocket, or wrap up the code in your own class to make this easier. Regards, Bob.