LarryChen
June 8th, 2010, 04:06 PM
I created a TCP server program. After the function accept is called, it is blocking and doesn't return. I wander what might cause the blocking?
|
Click to See Complete Forum and Search --> : Help with a blocking function accept LarryChen June 8th, 2010, 04:06 PM I created a TCP server program. After the function accept is called, it is blocking and doesn't return. I wander what might cause the blocking? MrViggy June 8th, 2010, 04:25 PM accept (http://msdn.microsoft.com/en-us/library/ms737526%28VS.85%29.aspx) will block if there is no connection present, and the socket is blocking. Viggy LarryChen June 8th, 2010, 05:41 PM Here is my code, //TCP client #include <WinSock2.h> #include <WS2tcpip.h> int _tmain(int argc, _TCHAR* argv[]) { char* str = "hi, there"; int len = strlen(str); char buffer[32]; sockaddr_in s; memset(&s, 0, sizeof(sockaddr_in)); s.sin_family = AF_INET; s.sin_addr.s_addr = inet_addr("127.0.0.1"); s.sin_port = htons(7); WSADATA wsadata; WSAStartup(MAKEWORD(2,2), &wsadata); SOCKET sock = socket(PF_INET,SOCK_STREAM, IPPROTO_TCP); if(sock == INVALID_SOCKET) { WSACleanup(); return 0; } if(connect(sock, (SOCKADDR*)&s, sizeof(s)) == SOCKET_ERROR) { WSACleanup(); return 0; } int strlength = strlen(str); if(send(sock, str, strlength, 0) != strlength) { WSACleanup(); return 0; } int totalBytesReceived = 0; int recvBytes = 0; while(totalBytesReceived < len) { recvBytes = recv(sock, buffer, 32, 0); } return 0; } //TCP server #include <WinSock.h> int _tmain(int argc, _TCHAR* argv[]) { sockaddr_in s; sockaddr_in clientS; int size = sizeof(clientS); s.sin_addr.s_addr = htonl(INADDR_ANY); s.sin_port = htons(7); s.sin_family = AF_INET; WSADATA wsaData; WSAStartup(MAKEWORD(2,2), &wsaData); SOCKET sock = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP); if(sock == INVALID_SOCKET) { WSACleanup(); return 0; } if(bind(sock, (sockaddr*)&s, sizeof(s)) == SOCKET_ERROR) { WSACleanup(); return 0; } if(listen(sock, 5) == SOCKET_ERROR) { WSACleanup(); return 0; } for(;;) { if(accept(sock, (sockaddr*)&clientS,&size) == INVALID_SOCKET) { WSACleanup(); return 0; } } WSACleanup(); return 0; } In the client side, the function call recv is also blocking. Can you find out anything with the code. Thanks. accept (http://msdn.microsoft.com/en-us/library/ms737526%28VS.85%29.aspx) will block if there is no connection present, and the socket is blocking. Viggy kolkoo June 9th, 2010, 12:01 AM You are using blocking sockets (the default ones) which means operations like accept and recv will block until they get something. If you don't that you can set the sockets to non-blocking. Anyway you should read up about it for example here -> http://tangentsoft.net/wskfaq/articles/io-strategies.html. LarryChen June 9th, 2010, 09:44 AM Actually I tried to use echo service in windows. I guess echo service is disabled, so that is why operation like accept and recv always block. How'd I know whether echo service is enabled in my computer(Windows XP)? You are using blocking sockets (the default ones) which means operations like accept and recv will block until they get something. If you don't that you can set the sockets to non-blocking. Anyway you should read up about it for example here -> http://tangentsoft.net/wskfaq/articles/io-strategies.html. LarryChen June 10th, 2010, 11:22 AM Can any guru here point out in the following code why the operations like accept and recv are blocking? Why didn't they get anything? From TCP client, I already sent the string to echo service port. I should expect to get the string back, right? BTW, I typed in the command "echo" under command line and it returns "echo is on.". Does it mean I have echo service enabled? Thanks for your help. Here is my code, //TCP client #include <WinSock2.h> #include <WS2tcpip.h> int _tmain(int argc, _TCHAR* argv[]) { char* str = "hi, there"; int len = strlen(str); char buffer[32]; sockaddr_in s; memset(&s, 0, sizeof(sockaddr_in)); s.sin_family = AF_INET; s.sin_addr.s_addr = inet_addr("127.0.0.1"); s.sin_port = htons(7); WSADATA wsadata; WSAStartup(MAKEWORD(2,2), &wsadata); SOCKET sock = socket(PF_INET,SOCK_STREAM, IPPROTO_TCP); if(sock == INVALID_SOCKET) { WSACleanup(); return 0; } if(connect(sock, (SOCKADDR*)&s, sizeof(s)) == SOCKET_ERROR) { WSACleanup(); return 0; } int strlength = strlen(str); if(send(sock, str, strlength, 0) != strlength) { WSACleanup(); return 0; } int totalBytesReceived = 0; int recvBytes = 0; while(totalBytesReceived < len) { recvBytes = recv(sock, buffer, 32, 0); } return 0; } //TCP server #include <WinSock.h> int _tmain(int argc, _TCHAR* argv[]) { sockaddr_in s; sockaddr_in clientS; int size = sizeof(clientS); s.sin_addr.s_addr = htonl(INADDR_ANY); s.sin_port = htons(7); s.sin_family = AF_INET; WSADATA wsaData; WSAStartup(MAKEWORD(2,2), &wsaData); SOCKET sock = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP); if(sock == INVALID_SOCKET) { WSACleanup(); return 0; } if(bind(sock, (sockaddr*)&s, sizeof(s)) == SOCKET_ERROR) { WSACleanup(); return 0; } if(listen(sock, 5) == SOCKET_ERROR) { WSACleanup(); return 0; } for(;;) { if(accept(sock, (sockaddr*)&clientS,&size) == INVALID_SOCKET) { WSACleanup(); return 0; } } WSACleanup(); return 0; } In the client side, the function call recv is also blocking. Can you find out anything with the code. Thanks. hoxsiew June 10th, 2010, 12:56 PM See posts 2 and 4 above. LarryChen June 10th, 2010, 01:20 PM My questions are based on the previous post. If there is no connection, then accept or recv are blocking. So my question is why there isn't connection. I posted my code and hopefully any guru here will point out what I did wrong or what I missed. See posts 2 and 4 above. hoxsiew June 10th, 2010, 05:44 PM I'm not sure what you are asking. accept() is supposed to block until a connection is actually present. See MSDN remarks on accept(): http://msdn.microsoft.com/en-us/library/ms737526(VS.85).aspx The accept function can block the caller until a connection is present if no pending connections are present on the queue, and the socket is marked as blocking. If the socket is marked as nonblocking and no pending connections are present on the queue, accept returns an error as described in the following. After the successful completion of accept returns a new socket handle, the accepted socket cannot be used to accept more connections. The original socket remains open and listens for new connection requests. and for recv(), if there is no connection, you should get an error. Again, see MSDN: http://msdn.microsoft.com/en-us/library/ms740121(v=VS.85).aspx The recv function is used to read incoming data on connection-oriented sockets, or connectionless sockets. When using a connection-oriented protocol, the sockets must be connected before calling recv. When using a connectionless protocol, the sockets must be bound before calling recv. As for echo, windows machines don't normally run an echo server. "echo" in a command prompt, is a command to turn echo on or off in the terminal and applies only to that instance of cmd.exe. As for you code snippit above, read the MSDN documentation, add some error checking and do some debugging. codeguru.com
Copyright Internet.com Inc., All Rights Reserved. |