Prev: How to include VLAN tag when sending packets?
Next: 2 differnt browsers cookies 'unsyncronised' ?!
From: papamms on 23 May 2010 23:32 On 5æ23æ¥, ä¸å8æ¶29å, David Schwartz <dav...(a)webmaster.com> wrote: > On May 21, 7:43 pm, papamms <ppmsn2...(a)gmail.com> wrote: > > > i run it under linux. from the blog linux actually support these > > timeouts. > > maybe my progarm send buff is full? and timeout didn't work? > > Why would you expect a perfectly healthy, 100% working connection to > timeout, regardless of what you set the timeout values to? Again, > these are *NOT* operation timeouts. They will not time out a perfectly > good connection on any sane implementation. > > DS you mean these are *NOT* operation timeouts. so can you tell me what's that? i had write some test code, and test it in lan. the connection is a perfectly healthy, 100% working . server work like this : accept connection and sleep, didn't recv any data, let tcp's window full client work like this: connect to server and send data again and again, print the log if i had set SO_SNDTIMEO, client didn't hang on send(), send() will return ; if i disable set SO_SNDTIMEO, cient will be hanged on send(); client log like this send time time 1274671226 need send 10000 send 10000 sum send 10000 end time 1274671226 1 usetime 0 send time time 1274671226 need send 10000 send 5976 x <= -1 sum send 5976 end time 1274671238 0 usetime 12 send time time 1274671238 need send 10000 x <= -1 sum send 0 end time 1274671244 0 usetime 6 send time time 1274671244 need send 10000 x <= -1 sum send 0 end time 1274671250 0 usetime 6 server code : // Module Name: Server.c // // Description: // This example illustrates a simple TCP server that accepts // incoming client connections. Once a client connection is // established, a thread is spawned to read data from the // client and echo it back (if the echo option is not // disabled). // // Compile: // cl -o Server Server.c ws2_32.lib // // Command line options: // server [-p:x] [-i:IP] [-o] // -p:x Port number to listen on // -i:str Interface to listen on // -o Receive only, don't echo the data back // #include <winsock2.h> #include <stdio.h> #include <stdlib.h> #define DEFAULT_PORT 8080 #define DEFAULT_BUFFER 4096 int iPort = DEFAULT_PORT; // Port to listen for clients on BOOL bInterface = FALSE, // Listen on the specified interface bRecvOnly = FALSE; // Receive data only; don't echo back char szAddress[128]; // Interface to listen for clients on // // Function: ClientThread // // Description: // This function is called as a thread, and it handles a given // client connection. The parameter passed in is the socket // handle returned from an accept() call. This function reads // data from the client and writes it back. // DWORD WINAPI ClientThread(LPVOID lpParam) { SOCKET sock=(SOCKET)lpParam; char szBuff[DEFAULT_BUFFER]; int ret, nLeft, idx; while(1) { // Perform a blocking recv() call // ::Sleep(1000); continue; } return 0; } // // Function: main // // Description: // Main thread of execution. Initialize Winsock, parse the // command line arguments, create the listening socket, bind // to the local address, and wait for client connections. // int main(int argc, char **argv) { WSADATA wsd; SOCKET sListen, sClient; int iAddrSize; HANDLE hThread; DWORD dwThreadId; struct sockaddr_in local, client; if (WSAStartup(MAKEWORD(2,2), &wsd) != 0) { printf("Failed to load Winsock!\n"); return 1; } // Create our listening socket // sListen = socket(AF_INET, SOCK_STREAM, IPPROTO_IP); if (sListen == SOCKET_ERROR) { printf("socket() failed: %d\n", WSAGetLastError()); return 1; } // Select the local interface and bind to it // if (bInterface) { local.sin_addr.s_addr = inet_addr(szAddress); if (local.sin_addr.s_addr == INADDR_NONE) return 0; } else local.sin_addr.s_addr = htonl(INADDR_ANY); local.sin_family = AF_INET; local.sin_port = htons(iPort); if (bind(sListen, (struct sockaddr *)&local, sizeof(local)) == SOCKET_ERROR) { printf("bind() failed: %d\n", WSAGetLastError()); return 1; } listen(sListen, 8); // // In a continous loop, wait for incoming clients. Once one // is detected, create a thread and pass the handle off to it. // while (1) { iAddrSize = sizeof(client); sClient = accept(sListen, (struct sockaddr *)&client, &iAddrSize); if (sClient == INVALID_SOCKET) { printf("accept() failed: %d\n", WSAGetLastError()); break; } printf("Accepted client: %s:%d\n", inet_ntoa(client.sin_addr), ntohs(client.sin_port)); hThread = CreateThread(NULL, 0, ClientThread, (LPVOID)sClient, 0, &dwThreadId); if (hThread == NULL) { printf("CreateThread() failed: %d\n", GetLastError()); break; } CloseHandle(hThread); } closesocket(sListen); WSACleanup(); return 0; } client code like this: #ifndef WIN32 # include <sys/epoll.h> # include <sys/types.h> # include <sys/socket.h> # include <arpa/inet.h> # include <netdb.h> # include <unistd.h> #include <fcntl.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <errno.h> #include <time.h> #define SOCKET int #define UINT32 unsigned int #endif #include <string> bool WriteHttpRequest( SOCKET &sClient, const std::string &request); bool SetSocket(SOCKET & sClient, UINT32 urecvout, UINT32 usendout); bool WriteHttpRequest( SOCKET &sClient, const std::string &request) { int needsend = request.length(); int sended = 0; int x; printf(" need send %d ", needsend); while (1) { x = send(sClient, request.c_str() + sended, needsend - sended , 0); if (x > 0) { printf(" send %d ", x); fflush(stdout); sended += x; if (sended >= needsend) { printf(" sum send %d", sended); return true; } } else if (x <=0) { printf(" x <= %d sum send %d ", x, sended); fflush(stdout); return false; } } return false;// end while } bool SetSocket(SOCKET & sClient, UINT32 urecvout, UINT32 usendout) { int x; UINT32 recvout = urecvout; // UINT32 sndout = usendout; // int len = recvout; #ifndef WIN32 struct timeval tv; tv.tv_usec = 0; tv.tv_sec = urecvout /1000 +1; x = setsockopt( sClient, SOL_SOCKET, SO_SNDTIMEO, &tv, sizeof(tv)); printf( "setsockopt SO_RCVTIMEO %d\n",x); tv.tv_sec = usendout /1000 +1; x = setsockopt( sClient,SOL_SOCKET, SO_RCVTIMEO, &tv, sizeof(tv)); printf( "setsockopt SO_SNDTIMEO %d\n",x); #endif return true; } int main() { int sClient; int ports = 8080; sClient = socket(AF_INET, SOCK_STREAM, 0); struct sockaddr_in clientadd ={0}; memset(&clientadd, 0 , sizeof(clientadd)); clientadd.sin_addr.s_addr = inet_addr("192.168.1.1"); clientadd.sin_family = AF_INET; clientadd.sin_port = htons(ports); if (connect(sClient, (struct sockaddr *)&clientadd, sizeof(clientadd)) == -1) { printf("connect fail"); return 0; } SetSocket(sClient, 5000, 25000); std::string request(10000, 'a'); while (1) { int lasttime = time(NULL); printf ("send time time %d ", lasttime); bool result = WriteHttpRequest( sClient, request); int timenow = time(NULL); printf (" end time %d %d usetime %d\n", timenow, result, timenow - lasttime); } return 0; }
From: David Schwartz on 25 May 2010 01:14 On May 23, 8:32 pm, papamms <ppmsn2...(a)gmail.com> wrote: > you mean these are *NOT* operation timeouts. Correct. They are *connection* timeouts. They timeout the connection itself, not the particular operation on it. > server work like this : accept connection and sleep, didn't recv any > data, let tcp's window full > > client work like this: connect to server and send data again and > again, print the log > > if i had set SO_SNDTIMEO, > client didn't hang on send(), send() will return ; > > if i disable set SO_SNDTIMEO, cient will be hanged on send(); As a consequence of the connection itself timing out, the operation timed out (since the operation is now impossible). However, since you cannot rely on the connection timing out, you cannot rely on the operation timing out as a consequence of it. In this case, what it just happens to do is what you just happen to want. But you want to time out the operation, not the connection. To get reliable behavior, you need to use an operation timeout. DS
From: David Schwartz on 25 May 2010 01:17 On May 24, 10:14 pm, David Schwartz <dav...(a)webmaster.com> wrote: > As a consequence of the connection itself timing out, the operation > timed out (since the operation is now impossible). However, since you > cannot rely on the connection timing out, you cannot rely on the > operation timing out as a consequence of it. In this case, what it > just happens to do is what you just happen to want. But you want to > time out the operation, not the connection. To get reliable behavior, > you need to use an operation timeout. For example, see this link: http://msdn.microsoft.com/en-us/library/ms740476%28VS.85%29.aspx Note that it says: "If a send or receive operation times out on a socket, the socket state is indeterminate, and should not be used; TCP sockets in this state have a potential for data loss, since the operation could be canceled at the same moment the operation was to be completed." That is, once a send or receive times out, the *CONNECTION* is dead. I don't recommend using these "timeouts" because they are sort of operation timeouts and sort of connection timeouts. DS
First
|
Prev
|
Pages: 1 2 Prev: How to include VLAN tag when sending packets? Next: 2 differnt browsers cookies 'unsyncronised' ?! |