Link to home
Start Free TrialLog in
Avatar of tflarsen
tflarsen

asked on

Datagram winsock programming in VC++ 5.0

I have a problem with configuring a socket to receive data on a datagram (connectionless) mode.

The other computer will send out a broadcast on port 0x5050 with a specific data field, so I do not know what MAC address to connect to.

The error listen() returns is WSAEOPNOTSUPP, which means the socket doesn't support listening... which I need to do.

The following lines are from my program, please tell me what I'm doing wrong or what I am missing.

Tnx
Ted

int i=0;
SOCKET MonitorRecvSocket;
SOCKADDR_IPX MonitorRecvSocketAddress;
char MonitorReceiveString[39];                  
for (i=0;i<40;i++)                        
  MonitorReceiveString[i] = '0';            
  MonitorRecvSocket = socket(AF_IPX, SOCK_DGRAM, NSPROTO_IPX);                        
  MonitorRecvSocketAddress.sa_family = AF_IPX;
  for (i=0;i<6;i++)
    MonitorRecvSocketAddress.sa_nodenum[i] = 'ÿ'; //ÿ = 0xFF for broadcast
  MonitorRecvSocketAddress.sa_socket = 0x5050;
  for (i=0;i<4;i++)
    MonitorSendSocketAddress.sa_netnum[i] = 0x00;
      if(bind(MonitorRecvSocket, (struct sockaddr *)&MonitorRecvSocketAddress, sizeof(MonitorRecvSocketAddress)) == SOCKET_ERROR)
{
  closesocket(MonitorRecvSocket);
  WSACleanup();
  exit(1);                                    
}      

if(listen(MonitorRecvSocket, 15) == SOCKET_ERROR)
{
  closesocket(MonitorRecvSocket);
  closesocket(MonitorSendSocket);
  WSACleanup();
  exit(1);
}
Avatar of tflarsen
tflarsen

ASKER

Adjusted points to 100
ASKER CERTIFIED SOLUTION
Avatar of piano_boxer
piano_boxer

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
could you tell me how to use setsockopt(); ?

I've tried to use it but I don't understand what it want me to put in for optval (A pointer to the buffer in which the value for the requested option is supplied).

About the WSAAsyncSelect(), is there a way to set a boolean to TRUE when data is ready to be read? I'm pretty much a newbie to VC++ AND winsock programming, so some examples of how to do it would be very much appreciated instead of just the function names (Even though that sure is a lot of help too)

Tnx
Ted
BOOL bTrue = TRUE;
setsockopt( socket, SOL_SOCKET, SO_BROADCAST, (char*)&bTrue, sizeof(bTrue) );


There is now way of getting a BOOL value set when data is ready to be received.
You would need to make use of the WSAAsyncSelect() function.

Or, switch to CSocket MFC class it will make it a bit easyer.
I wouldn't mind changing the way I'm trying to do things, but I have only very limited time to finish the communication. Actually it's due for tomorrow morning and it's now 9:00 pm here.

Anyway, I'm still experiencing problems with the receive part of the communications. I've managed to get the send working properly (almost, as it puts in 5 more bytes than i've specified, don't know if they are checksums or something like that).

I've put up a statement like this:

BOOL DataReady = TRUE;

if(setsockopt( MonitorRecvSocket, SOL_SOCKET, SO_BROADCAST, (char*)&DataReady, sizeof(DataReady)) != 0)
{
  MessageBox("Error on MonitorRecvSocket", "Internal program error", MB_OK);
  WSACleanup();
  exit(1);
}
DataReady = FALSE;

//Here comes a send part to the other computer, which then returns a broadcast to port 5050, which you can see in the original question

if (bind (MonitorRecvSocket, (struct sockaddr *)&MonitorRecvSocketAddress, sizeof(MonitorRecvSocketAddress)) == SOCKET_ERROR)
{
//error handler here
}

while(DataReady != TRUE && timer1 < 10)
{
  Sleep(1000);
  send(MonitorSendSocket, MonitorRequestString, strlen
  MonitorRequestString), MSG_DONTROUTE);
  timer1++;
}
if (timer1 == 10) //Timeout limit
{
  messageBox("Error", "Timeout!", MB_OK);
  closesocket(MonitorSendSocket);
  closesocket(MonitorRecvSocket);
  WSACleanup();
  exit(1);
}

if (recv(MonitorRecvSocket, MonitorReceiveString, 39,MSG_OOB) == SOCKET_ERROR)
{
 //another errorhandler
}

The other program sends data, but the DataReady boolean is never changed. I've checked the communication on a third computer using NetXray and it does indeed send to port 5050.

So somewhere there is an error...
Calling recv right afterwards doesn't make any differences. If I do that it returns an unspecified return code.
It's like the socket is set up wrong, or the socket address is wrong.

Please help and please be quick, as it is for my final exams project.
Adjusted points to 150
Ok, just now realised that I forgot to make use of WSAAsyncSelect()... Hmm.. how do I use that one?

Sorry for asking all these questions, I'm just feeling quite a bit lost.

Anyway, I got the send working and the recv doesn't give an error now that I changed it to MSG_PEEK instead of MSG_OOB.

So now I think it's only the WSAAsyncSelect() I need to set up properly.

Do I have to specify a certain hWnd and if so, what should it be?
Hang in there.
I'll try to write a more complete sample fore you.