Re: Inconsistency in TCP sockets behavior between Windows and Linux



The program is buggy to rely on such a thing. TCP does not guarantee this
behavior at all, you need to use a graceful close if you want any assurances
of data reception by the remote endpoint.

An RST is an indication that the connection should be abandoned as soon as
possible, not after all of the graceful shutdown semantics (like processing
of recently sent data and acknowledgement that the connection is dead).

From RFC 793: "TRANSMISSION CONTROL PROTOCOL"
ftp://ftp.rfc-editor.org/in-notes/rfc793.txt

"
If the RST bit is set then, any outstanding RECEIVEs and SEND
should receive "reset" responses. All segment queues should be
flushed. Users should also receive an unsolicited general
"connection reset" signal. Enter the CLOSED state, delete the
TCB, and return.
"

"Rafi" <Rafi@xxxxxxxxxxxxxxxxxxxxxxxxx> wrote in message
news:B4969768-A831-4FA5-9972-D83BA9C553B3@xxxxxxxxxxxxxxxx
Hi,
There is an inconsistency in TCP sockets behavior between Windows and
Linux,
and I think that Linux behavior is more reasonable.
There are client and server applications.
Server creates a listening socket and waits for incoming TCP connection.
Client connects to the server, sends some amount of data (say 100 bytes)
and
then abortively closes the connection. This is done by setting linger (ON,
delay 0) option on client side socket.
Server accepts the connection but 'recv' fails with 10054 (CONNRESET)
although network sniffer (ethereal) shows the data has successfully
arrived
at the server side and TCP ACK was sent (from Server to Client).
If Client would delay a bit (say Sleep for a second) it works fine, the
'recv' succeeds to receive the sent buffer. On Linux the same program
works
fine; that is the sent buffer can be read regardless the reset connection.
I think it is unreasonable that 'recv' operation works in different way
depending on the time when it was called, before or after TCP RST has
arrived.

The programs demonstrating this behavior follows. The same program works
as
client and server. Server binds to port 23456 and should be called without
arguments. In order to run the program as a client, run it with the
following
arguments: -c -d server_ip_address.
This program should compile on windows and Linux.

#ifndef _WIN32
#include <netdb.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/select.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <errno.h>
#else
#include "windows.h"
#include "winsock.h"
#endif
#include <string.h>
#include <stdio.h>

int isServ = 1;
char *destIp = "";
unsigned short port = 23456;

/*
* usage
* to run as server: -s
* to run as client: -c -d server_ip_address
*/


#ifndef _WIN32
#define closesocket close
#define Sleep(n) usleep(n*1000)
#endif

int main(int argc, char** argv)
{
struct sockaddr_in sa;
int s;
int cnt, ret, addrLen;
char buff[100];


#if _WIN32
{
WORD wVersionRequested;
WSADATA wsaData;
wVersionRequested = 0x0101;
WSAStartup(wVersionRequested, &wsaData);
}
#endif

for (cnt = 1; cnt < argc; cnt++)
{
if (!strcmp(argv[cnt],"-s"))
isServ = 1;
else if (!strcmp(argv[cnt],"-c"))
isServ = 0;
else if (!strcmp(argv[cnt],"-d"))
destIp = argv[++cnt];
else
printf("wrong usage\n");
}

memset(&sa,0,sizeof(sa));
sa.sin_family = AF_INET;
sa.sin_port = htons(port);
if (isServ)
sa.sin_addr.s_addr = INADDR_ANY;
else
sa.sin_addr.s_addr = inet_addr(destIp);
addrLen = sizeof(sa);

s = socket(AF_INET,SOCK_STREAM,0);
if (s < 0)
{
printf("failed to create socket \n");
exit(0);
}

if (isServ)
{
int ns,err;
struct sockaddr_in nsa;

printf("running as server\n");

if (bind(s,(struct sockaddr*)&sa, addrLen) < 0)
{
printf("failed to bind the socket\n");
exit(0);
}

if (listen(s,10) < 0)
{
printf("failed to listen on the socket\n");
exit(0);
}

addrLen = sizeof(nsa);
ns = accept(s,(struct sockaddr*)&nsa, &addrLen);
if (ns < 0)
{
printf("failed to accept\n");
exit(0);
}

printf("accepted client connection from %s:%d\n",
inet_ntoa(nsa.sin_addr),ntohs(nsa.sin_port));


/* sleep for a while; lets other side to reset the connection */
printf("going to sleep for a while ...\n");
Sleep(1000);

printf("awake, try to read from the socket ...\n");
ret = recv(ns,buff,sizeof(buff),0);
#ifdef _WIN32
err = WSAGetLastError();
#else
err = errno;
#endif
printf("Recv returns with %d, error %d\n",ret,err);
closesocket(ns);
closesocket(s);
}
else
{
struct linger l;

/* set the linger, for abortive close */
l.l_onoff = 1;
l.l_linger = 0;
if (setsockopt(s,SOL_SOCKET,SO_LINGER,(char*)&l,sizeof(l)) < 0)
{
printf("failed to to set linger\n");
exit(0);
}

if (connect(s,(struct sockaddr*)&sa, addrLen) < 0)
{
printf("failed to to connect\n");
exit(0);
}

ret = send(s,buff,50,0);
if (ret != 50)
{
printf("failed to send\n");
exit(0);
}

/* if client Sleep, server running on Windows works fine, otherwise
server 'recv' fails */
/*Sleep(3000);*/

closesocket(s);

printf("connected, sent and closed the socket\n");
}

return 0;

}



.



Relevant Pages

  • Re: Help with deceiding on best solution
    ... the client is always establishing the connection. ... it *will* establish a TCP connection to interact with a Web server. ...
    (microsoft.public.dotnet.framework.compactframework)
  • Re: .Net Scalability problem
    ... LoadRunner will peak out a server with a few virtual users. ... To get an idea of load, ... Fire off the test client and watch the number of ... > So I think that the MTC generate concurrent connection and per ...
    (microsoft.public.dotnet.framework.adonet)
  • Re: Connection lost at same time every hour (sometimes)
    ... After making the two following alterations on the server the problem seems ... After analyze your ipconfig on SBS and client, ... Then, other connection is good, ...
    (microsoft.public.windows.server.sbs)
  • Re: server disconnection - very often
    ... Reason of permanent popups is VMware server aplication on clients. ... Run CEICW to configure the network of SBS: ... Two network adapters - manual router connection to broadband ... Uninstall VMware on client. ...
    (microsoft.public.windows.server.sbs)
  • Re: Lan setup 2 nic
    ... The external nic only has TCP/IP enabled. ... Ipconfig of the server is looking good, but the client is still missing the ... > connection so we have a 2 nic with router setup now. ...
    (microsoft.public.windows.server.sbs)