Click to See Complete Forum and Search --> : recvfrom() throwing an exception..?


JMS
October 3rd, 2005, 12:18 PM
Problem:
When I call recvfrom() an exception is fired saying.
"The thread 0xF36 has exited with code 0(0x0)." leaving me no clue as to what just happenned.


Background
I am writing a class which is communicating with udp sockets.. I call WSAStartup() in the console programs main(). I then instantiate a class. Inside this class I spawn a UDP listening thread. Inside this listening thread
I instatiate my socket, bind my socket, and finally call recvfrom().. The recvfrom() caughs up a fur ball and blows me out of my thread with a very unhelpful exception.. ( see problem statement above).

Am I doing anything obviously wrong? Here is my code... For instance do I need to set a flag or anything saying I'm doing this in parelel threads? Any help would be very very appreciated.. thanks..


MAIN



#include "stdafx.h"
#include <winsock.h>
#include "conduit.h"

int main(int argc, char* argv[])
{
WSADATA wsaData;

if( WSAStartup( MAKEWORD(1,1), &wsaData) != 0)
{
fprintf( stderr, "WSAStartup failed.\n");
exit(1);
}

CConduit conduit(0,0,0);

WSACleanup();
return 0;
}


Server Thread called inside my CConduit class

#include "stdafx.h"
#include "winsock.h"
#include "ThreadListeners.h"

UINT ThreadProcUDPListener( LPVOID pParam )
{
int socket_type = SOCK_DGRAM;
struct sockaddr_in local, from;
int fromlen = 0;
int retval;
char Buffer[128];

unsigned short port = DEFAULT_UDP_PORT;
char *interface = NULL;
SOCKET listen_socket, msgsock;;


local.sin_family = AF_INET;
// local.sin_addr.s_addr = (!interface)?INADDR_ANY:inet_addr(interface);
local.sin_addr.s_addr = INADDR_ANY;

/*
* Port MUST be in Network Byte Order
*/
local.sin_port = htons(port);


if( INVALID_SOCKET == (listen_socket = socket(AF_INET,socket_type,0)))
{
fprintf(stderr,"socket() failed with error %d\n",WSAGetLastError());
WSACleanup();
return -1;
}

//
// bind() associates a local address and port combination with the
// socket just created. This is most useful when the application is a
// server that has a well-known port that clients know about in advance.
//
if (bind(listen_socket,(struct sockaddr*)&local,sizeof(local)) == SOCKET_ERROR)
{
fprintf(stderr,"bind() failed with error %d\n",WSAGetLastError());
WSACleanup();
return -1;
}

while(1)
{
fromlen =sizeof(from);
msgsock = listen_socket;

// for SOCK_DGRAM (UDP), the server will do
// recvfrom() and sendto() in a loop.
retval = recvfrom(msgsock,Buffer,sizeof(Buffer), 0,
(struct sockaddr *)&from,&fromlen);

printf("Received datagram from %s\n",inet_ntoa(from.sin_addr));

if (retval == SOCKET_ERROR)
{
fprintf(stderr,"recv() failed: error %d\n",WSAGetLastError());
closesocket(msgsock);
continue;
}

if (retval == 0) {
printf("Client closed connection\n");
closesocket(msgsock);
continue;
}

printf("Received %d bytes, data [%s] from client\n",retval,Buffer);

printf("Echoing same data back to client\n");

retval = sendto(msgsock,Buffer,sizeof (Buffer),0,
(struct sockaddr *)&from,fromlen);

if (retval == SOCKET_ERROR)
{
fprintf(stderr,"send() failed: error %d\n",WSAGetLastError());
}

if (socket_type != SOCK_DGRAM)
{
printf("Terminating connection\n");
closesocket(msgsock);
}
else
printf("UDP server looping back for more requests\n");
}


return 0; // thread completed successfully
}


UINT ThreadProcTCPListener( LPVOID pParam )
{
return 0; // thread completed successfully
}

Marc G
October 3rd, 2005, 12:32 PM
[ moved thread ]

JMS
October 3rd, 2005, 01:08 PM
I think I found my problem... Knew I was doing something dumb...

My class tConduit spawns the thread to listen for the socket.. then it returns... where the main program shutsdown the socket and returns out from under my listener thread..

thus when the listener fires up recvfrom the WSACleanup(); call has already been made and the call just falls out...



I found this by moving the server function into the main thread and observing that it all worked correctly.. Then thinking about what was actually happenning.. and finally beating myself about the head and facial area's for not getting it right off...