Click to See Complete Forum and Search --> : back to basics :( error 10054


drewdaman
January 4th, 2005, 03:35 PM
hello everyone

i'm having a little trouble here. i have to modify my code (which works perfectly in my original setup) to do something ... it has to be modified for a demo and i just have to keep things simple for this.

when i tried to modify, i am getting error 10054 which is:

Connection reset by peer.
An existing connection was forcibly closed by the remote host. This normally results if the peer application on the remote host is suddenly stopped, the host is rebooted, the host or remote network interface is disabled, or the remote host uses a hard close (see setsockopt for more information on the SO_LINGER option on the remote socket). This error may also result if a connection was broken due to keep-alive activity detecting a failure while one or more operations are in progress. Operations that were in progress fail with WSAENETRESET. Subsequent operations fail with WSAECONNRESET.


I don't really see how this could be happening from my code! when i run the code, the client exits with error code 10054.

i create an instance of the client and server and call tcpinitial on both (of course in separate projects). Everything works except for the receive in the client. This should become clear if you take a look at the code below. That is what is causing the problem. The error occurs at the line

nret=recv(tcpSocket, msg, 100,0);

of the TCPinitial function in the client. I have marked the line in the code as well, you can't miss it! :)

A call to WSAGetLastError after the above line gives error 10054.

relevant code for server:


Server::Server(){
nLen = sizeof(SOCKADDR);
channel=0;
buffSize=1000;
curFileName="long.txt";
int nret;

WORD wVersionRequested = MAKEWORD(1,1);
WSADATA wsaData;
int nRet;
nRet = WSAStartup(wVersionRequested, &wsaData);
if (wsaData.wVersion != wVersionRequested)
{
fprintf(stderr,"\n Wrong version\n");
return;
}

listeningSocket = socket(AF_INET, // Go over TCP/IP
SOCK_STREAM, // This is a stream-oriented socket
IPPROTO_TCP); // Use TCP rather than UDP



serverInfo.sin_family = AF_INET;
serverInfo.sin_addr.s_addr = INADDR_ANY; // Since this socket is listeningfor connections,
// any local address will do
serverInfo.sin_port = htons(nPort); // Convert integer 8888 tonetwork-byte order
// and insert into the port field

// Bind the socket to our local server address
nret = bind(listeningSocket, (LPSOCKADDR)&serverInfo, sizeof(struct
sockaddr));


// Fill in the address structure
//


saServer.sin_family = AF_INET;
saServer.sin_addr.s_addr = INADDR_ANY; // Let WinSock assign address
saServer.sin_port = htons(nPort); // Use port passed from user
}//end constructor

int Server::sendTCPinitial(){
int chan; //variable to hold the channel number sent by the client.
int nret;
char *incoming = new char[1];
char * outgoing=new char[50];

// Make the socket listen
nret = listen(listeningSocket, 10); // Up to 10 connections may wait at any
// one time to be accept()'ed

// Wait for a client


theClient = accept(listeningSocket,
NULL, // Address of a sockaddr structure (see explanation below)
NULL); // Address of a variable containing size of sockaddr struct



//receive the channel number
recv(theClient, incoming, 1, 0);
chan=atoi(incoming);
//send message to client.
//cout<<"channel is:" <<chan<<endl;
outgoing=getTCPmessage (getFileSize(curFileName));
// cout<<endl<<"outgoing is: " <<strlen(outgoing)<<endl;
send(theClient, outgoing, strlen(outgoing), 0);

return chan;

}



relevant code for client:

//constructor
Client::Client(){
channel=0;
buffSize=0;
curFileSize=0;

WORD wVersionRequested = MAKEWORD(1,1);
WSADATA wsaData;
int nRet;


// Initialize WinSock and check the version

nRet = WSAStartup(wVersionRequested, &wsaData);
if (wsaData.wVersion != wVersionRequested)
{
fprintf(stderr,"\n Wrong version\n");
return;
}

tcpSocket = socket(AF_INET, // Go over TCP/IP
SOCK_STREAM, // This is a stream-oriented socket
IPPROTO_TCP); // Use TCP rather than UDP



serverInfo.sin_family = AF_INET;
serverInfo.sin_addr.s_addr = inet_addr("10.0.0.76");

serverInfo.sin_port = htons(nPort); // Change to network-byte order and
// insert into port field


// Fill in the address structure for the server



saServer.sin_family = AF_INET;
//saServer.sin_addr = *((LPIN_ADDR)*lpHostEntry->h_addr_list);
// ^ Server's address
saServer.sin_addr.s_addr = inet_addr("10.0.0.76");

saServer.sin_port = htons(nPort); // Port number from command line
} //end contructor

void Client::TCPinitial(int ch){

char *channel=new char[1];

itoa(ch,channel,10);
int nret;
char * msg=new char[100];//="This is the client";
int l=strlen(channel);
// Create the socket



nret = connect(tcpSocket,
(LPSOCKADDR)&serverInfo,
sizeof(struct sockaddr));
/* if (nret == SOCKET_ERROR)
{
PRINTERROR("connect()");
closesocket(tcpSocket);
return;
}*/
//Send channel number
nret=send (tcpSocket, channel, l, 0);
if (nret == SOCKET_ERROR)
{
PRINTERROR("send()");
closesocket(tcpSocket);
return;
}

//int brec;
//**********************ERROR HAPPENS HERE*********************
nret=recv(tcpSocket, msg, 100,0);
cout<<WSAGetLastError(); //GIVES ERROR 10054
//*************************************************************
if (nret == SOCKET_ERROR)
{
PRINTERROR("recv()");

}
}



Hoping someone can help me out here! i'm a little confused! thanks!

Mathew Joy
January 5th, 2005, 07:59 AM
Did you try in different machines?

Do you have the connection when you call recv? Try netstat from command promt or SO_CONNECT_TIME sock opt just before calling recv.

Is that your original code or have you deleted the error handling codes? I don't see them in your server code. Also there is no reason why you should comment those codes, even if you are sure that there is no error happening at that time(for instance while stepping in).

drewdaman
January 5th, 2005, 11:31 AM
hi Matthew,

yeah you're right, i should put the error handling code there. but i am certain that everything works until the recv call. i tried it incrementally, just to find out where the problem is. there is such a small number of messages exchanged so far that it wasn't too hard to do this!

i tried using SO_CONNECT_TIME like you suggested. it returns 0. i'm guessing that this is the time in seconds that the socket has been connected - this is waht i gathered from what i read on the web about it. if it is in whole seconds, then 0 seems fine because i'm testing on my local machine (so it should be really fast) and it shouldn't take nearly a whole second to do the stuff before that. please correct me if i am wrong.

i guess i'm having trouble here because most of the socket stuff i did earlier (you've responded to a ton of my posts so i think you mgiht remember!) was with UDP and i don't have much experience with TCP.

any further help will be much appreciated!
thanks.

drewdaman
January 5th, 2005, 12:08 PM
hi again,

i forgot to try your suggestion of using different computers last time i replied. i just did that. but i don't think you've checked this since then .. so its cool! :) i ran the server on one machine and the client on the other. it works when i do this :S (which is great! but it should still work on the local machine too!)

do you know why it doesn't work when i try to do everything on one machine locally?

thanks,
drew.

ps. just a thought... i don't really have anything to back this up... but do you think this sort of problem could arise if winsock is not being cleaned up properly? i have a function called "destroy". i call that when i am done .. all i have in there is the line: "WSACleanup();"

Mathew Joy
January 7th, 2005, 11:21 AM
No, I don't think has something to do with not calling WSACleanup(). It is more likely to be some external interference in the form of some third party driver, filter or firewall. When using the same machine try connecting to the loop back interface 127.0.0.1 and see if you get the same behavior.

One thing I forgot to say is, never do the app testing on one machine(ie both server and client). Several properties of TCP is disabled or will not show. You can do that sort of testing just to make sure you code is OK.

LeoB
January 26th, 2005, 12:33 PM
Did you come any further on this? I might have a similar issue (recv, 10054, 127.0.0.1). The error occurs after 4 minutes for me.

drewdaman
January 27th, 2005, 10:02 AM
make sure termination of the application does not affect sending/receving. a temporary way to fix it would be to put an infinite while loop at the end of your main method.

Andreas Masur
January 27th, 2005, 01:04 PM
a temporary way to fix it would be to put an infinite while loop at the end of your main method.
And that would help with what? :confused:

Mathew Joy
January 27th, 2005, 01:20 PM
And that would help with what? :confused:
That would help with app not closing right after the send(). But obviously a poor way. :thumbd:

drewdaman
January 27th, 2005, 01:25 PM
That would help with app not closing right after the send(). But obviously a poor way. :thumbd:

yes, a very poor way! but, that is why i called it a "temporary" way to do it! just so you can test other stuff.... eventually, the application would most likely be running in some sort of a loop and this problem wouldn't occur till the app is finally closed. also, just a way to see if closing the app is, in fact, your problem!