problem about "can't assign requested address"

Hi,

I am using udp to communicate between two QNX nodes(run in vmvare). But I had encounted a problem (can’t assign requested address) when sended a data to another node using sendto. I really confused. Could someone give a help? I would be really appreciate it.

Juvin

It means the adresses your sending is illegal.

mario,

Thanks for your reply.
The detailed situation is: In node1,run a process A, which will first spawn a process B to run in node2, the process B will send a data back to process A, then process A do something and send a data to process B. repeat…

Now the first send (process B-----> process A) can work successfully. but the second send ( process A -----> process B) does not work. The sendto function of process A returns normally, but process B blocks in recvfrom function. In addition, during the procedure, I used two socket fd so that the two send procedure do not affect each other.
Also, in each process, if I bind the two socket fd, in node2, they all retrun 0; but in node1, one bind return 0, the other bind return -1 , the error is “can’t assign requested address”.

I really have no idea about this. Could you help me?
Thanks in advance.

Juvin,

Can you post your socket code along with the IP address/ports used on both machines.

Tim

Hi, Tim
Thanks

/* File: server.c */

#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <spawn.h>
#include <errno.h>
#include <unistd.h>
#include <sys/select.h>

double number = 1.0;
int LoopNumber = 5;
int fdc,fds;
struct sockaddr_in addr,c_addr;
socklen_t len = sizeof(addr);

void ServerRecvfromClient()
{
char buf[30]="";
printf(“before Server receive…\n”);
recvfrom(fds, buf, 30, 0, (struct sockaddr *)&c_addr, &len);
printf("\n: Server Received data: %s \n",buf);
number = atof(buf);
}

void ServerSendtoClient(double temp)
{
char buf[30]= “”;
int n = 0;
printf(“before Server sends…\n”);
sprintf(buf, “%f”, temp);
if ((n=sendto(fdc, buf, strlen(buf)+1, 0, (struct sockaddr *)&c_addr, sizeof(c_addr)))<0 )
{
printf(“Server sends to Client error\n”);
}
printf(" Server sended %s\n",buf);

}

int main(int argc, char **argv)
{

int n;
pid_t pid;
int ret;
int on = 1;

fds = socket(AF_INET, SOCK_DGRAM, 0); //SOCK_DGRAM
fdc = socket(AF_INET, SOCK_DGRAM, 0);

setsockopt(fds, SOL_SOCKET,SO_REUSEADDR,&on, sizeof(on));
//Server addr
bzero(&addr, sizeof(addr));
addr.sin_family = AF_INET;
addr.sin_addr.s_addr = htonl(INADDR_ANY);
addr.sin_port = htons(ServerPort);

ret = bind(fds, (struct sockaddr *)&addr, sizeof(addr));
printf(“Server subsystem bind local %d\n”,ret);
if(ret < 0) printf("%s\n", strerror(errno));

//Client addr
bzero(&c_addr, sizeof(c_addr));
c_addr.sin_family = AF_INET;
c_addr.sin_addr.s_addr = inet_addr(Node2_IP);
c_addr.sin_port = htons(ClientPort);

struct inheritance inherit_Client;
char *file_Client="/home/test/Client";
char *Client_arg_list[] = {file_Client, NULL};
inherit_Client.flags = SPAWN_SETND|SPAWN_NOZOMBIE;
inherit_Client.nd = netmgr_strtond(“node2”,NULL);

if(pid = spawn(file_Client,0,NULL,&inherit_Client ,Client_arg_list,NULL) == -1)
{
printf(“spawn error!”);
exit(-1);
}

while(LoopNumber–)
{
ServerRecvfromClient();
ServerSendtoClient(number);
} //end while
return 0;
}

/******************* file: Client.c ******************/

#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <netdb.h>
#include <errno.h>
#include <string.h>
#include <stdlib.h>
#include <stdio.h>

int fdc,fds;
int LoopNumber = 5;
struct sockaddr_in remote_addr,local_addr;
socklen_t len = sizeof(remote_addr);
double number = 1.0;

void ClientSendtoServer(double temp)
{
char buf[30]= “”;
int n = 0;
printf(“before Client sends…\n”);
sprintf(buf, “%f”, temp);
if ((n=sendto(fds, buf, strlen(buf)+1, 0, (struct sockaddr *)&remote_addr, sizeof(remote_addr)))<0 )
{
printf(“Client sends to Server error\n”);
printf("%s\n", strerror(errno));
}
printf(" Client sended %s\n",buf);
}

void ClientRecvfromServer()
{
char buf[30]="";
int n;
printf(“before Client receives…\n”);
n = recvfrom(fdc, buf, 30, 0, (struct sockaddr *)&remote_addr, &len);
printf("\n: Client Received %d data: %s \n",n,buf);
number = atof(buf);
number = number + 0.1;
}

int main(int argc, char **argv)
{
fds = socket(AF_INET, SOCK_DGRAM, 0);
fdc = socket(AF_INET, SOCK_DGRAM, 0);
int ret;

//server addr
bzero(&remote_addr, sizeof(remote_addr));
remote_addr.sin_family = AF_INET;
remote_addr.sin_addr.s_addr = inet_addr(Node1_IP);
remote_addr.sin_port = htons(ServerPort);
//client addr
bzero(&local_addr, sizeof(local_addr));
local_addr.sin_family = AF_INET;
local_addr.sin_addr.s_addr = htonl(INADDR_ANY);
local_addr.sin_port = htons(ClientPort);

ret = bind(fdc, (struct sockaddr *)&local_addr, sizeof(local_addr));
if(ret < 0) printf("%s\n", strerror(errno));

while(LoopNumber–)
{
ClientSendtoServer(number);
ClientRecvfromServer();
}
return 0;
}

Juvin,

While your example is not the ideal way to use sockets code wise, it should still work.

However, I don’t see any definitions for:

Node2_IP
ClientPort
ServerPort

anywhere in your code. Can you post that information.

My guess is that Node2_IP or ClientPort is incorrect which is why you can’t bind properly on the server side. Also, there is only 1 bind in each process but you described 2 binds in your prior post, one working and one not working. But there is only 1 actual bind in the server code. So I am not sure why you think there should be 2 binds.

Tim

Juvin, your code is incorrect. In both examples a socket is used before properly configured.
Also, as Mario and Tim already said, you are probably passing wrong arguments to one or more of the bind() calls.
Also, your explanation why you use two sockets instead of one is based on misconception of coding in C and unix files and streams.

However, I am pretty sure you can figure it out yourself using simple examples and experimentation.
There are many examples on the internet which demonstrate udp client-server or peer-to-peer mechanisms.

Hi Tim,

Thanks for your time and consideration!

I defined the information as below, I just deleted that when post the code.
#define Node2_IP “10.10.33.86”
#define Node1_IP “10.10.33.120”
#define ServerPort 3000
#define ClientPort 4000
BTW, the IP was configured by DHCP.

I also delete some code in the server.c, I used two “bind” as this
//Server addr
bzero(&addr, sizeof(addr));
addr.sin_family = AF_INET;
addr.sin_addr.s_addr = htonl(INADDR_ANY);
addr.sin_port = htons(ServerPort);

ret = bind(fds, (struct sockaddr *)&addr, sizeof(addr));
printf(“Server subsystem bind local %d\n”,ret);
if(ret < 0) printf("%s\n", strerror(errno));

//Client addr
bzero(&c_addr, sizeof(c_addr));
c_addr.sin_family = AF_INET;
c_addr.sin_addr.s_addr = inet_addr(Node2_IP);
c_addr.sin_port = htons(ClientPort);

ret = bind(fdc, (struct sockaddr *)&c_addr, sizeof(c_addr));
printf(“Server subsystem bind remote %d\n”,ret);
if(ret < 0) printf("%s\n", strerror(errno));

I am really confused why the code does not work, so I try to bind the two socket fd to test if they can work. I am not sure if this is a right way.
All I want to do is implement a “point to point” communication using UDP for a distributed computing, since the communication should not affect the execution order predefined, so I want to use a socket fd for each communication.

Any suggestions of you will be appreciated.
Thanks again!

Hi, mezek

To be honest, I do not know the detailed socket mechanism, I just write the code according some examples. I will take more example as reference and recheck the code. I hope this is not something related with VMvare. Thank you very much.

When you create udp socket you have to bind it before using it. Since you had 2 udp sockets and only 1 bind something must be wrong.

I suppose the VMware networking must be configured properly as well (bridged and host-only mode should be fine, but in nat mode there is some configuration needed).

One udp socket can receive from and send to multiple counterparts just fine.

Also in the code above I fail to see any transfer rate control.

Juvin,

OK, I copied your code and compiled it. I found a bunch of warnings. So my first question is: Are you compiling in QNX 4 or QNX 6?

Next, I looked at the 2nd bind in your code update. The reason you are getting the error is that you can’t bind to a remote machine IP address since it’s not your own address. There is no need to bind to the remote socket and in any case, it’s not legal to do so.

Next, once I got it compiled, I just changed the IP addresses to 2 nodes on my network and took out the remote spawn (which makes me think you are compiling on QNX 4) and just manually started on both sides.

I then saw what you did with the server not responding. It took me a while (plus tcpdump) to figure out what’s going on. In your ServerReceiveFromClient code you are overwriting the c_addr struct that you filled out in main(). What happens is that when you get the packet from the client, the port is not 4000 (this is because the bind command changes your port). So when you resend back to the client, you are sending to the wrong port. Once I hardcoded port 4000 back into c_addr struct it worked fine (note, you’ll also have to hardcode 3000 into the remote_addr in your client code too).

You shouldn’t overwrite your structs if you know the ports beforehand. You should use temp variables in your receive routines to prevent this. Normally, the Server has a fixed port (say 3000) and the client knows this and always sends to 3000. The Server then just replies to the port it gets in the receivefrom command (that’s what you currently have). In that case, your Client code only needs 1 socket (not 2).

There is an excellent example here (the UDP one is at the bottom of the page) you can use as the basis for your code. It only sends 1 packet but you can easily add your loop in to send the 5 you were sending.

beej.us/guide/bgnet/output/html/ … erver.html

Tim

Thanks for you guys’ kindly help, I really appreciate it. Now the program works. This really encouraged me. Thanks again! :smiley: :smiley: