Solved

Datagram winsock programming in VC++ 5.0

Posted on 1998-04-13
8
498 Views
Last Modified: 2013-11-20
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);
}
0
Comment
Question by:tflarsen
  • 5
  • 3
8 Comments
 

Author Comment

by:tflarsen
ID: 1317646
Adjusted points to 100
0
 
LVL 4

Accepted Solution

by:
piano_boxer earned 150 total points
ID: 1317647
1. (NOTE): It is necessary to call setsockopt() with SO_BROADCAST flag set, in order to receive IPX broadcasts on Windows 95.

2. What you are trying to do is listen for connections on a connection-less protocol!....... that is not possible.

3. Instead of calling listen you should call WSAAsyncSelect() with FD_READ parameter. This will post a message to your window when data is ready for reading on the socket.

4. When you receive the massage call recv() to read the data from the socket.

0
 

Author Comment

by:tflarsen
ID: 1317648
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
0
Gigs: Get Your Project Delivered by an Expert

Select from freelancers specializing in everything from database administration to programming, who have proven themselves as experts in their field. Hire the best, collaborate easily, pay securely and get projects done right.

 
LVL 4

Expert Comment

by:piano_boxer
ID: 1317649
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.
0
 

Author Comment

by:tflarsen
ID: 1317650
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.
0
 

Author Comment

by:tflarsen
ID: 1317651
Adjusted points to 150
0
 

Author Comment

by:tflarsen
ID: 1317652
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?
0
 
LVL 4

Expert Comment

by:piano_boxer
ID: 1317653
Hang in there.
I'll try to write a more complete sample fore you.

0

Featured Post

Announcing the Most Valuable Experts of 2016

MVEs are more concerned with the satisfaction of those they help than with the considerable points they can earn. They are the types of people you feel privileged to call colleagues. Join us in honoring this amazing group of Experts.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Introduction: Dynamic window placements and drawing on a form, simple usage of windows registry as a storage place for information. Continuing from the first article about sudoku.  There we have designed the application and put a lot of user int…
Introduction: Displaying information on the statusbar.   Continuing from the third article about sudoku.   Open the project in visual studio. Status bar – let’s display the timestamp there.  We need to get the timestamp from the document s…
This video will show you how to get GIT to work in Eclipse.   It will walk you through how to install the EGit plugin in eclipse and how to checkout an existing repository.
Finds all prime numbers in a range requested and places them in a public primes() array. I've demostrated a template size of 30 (2 * 3 * 5) but larger templates can be built such 210  (2 * 3 * 5 * 7) or 2310  (2 * 3 * 5 * 7 * 11). The larger templa…

806 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question