2 snowpino snowpino 于 2013.10.10 09:51 提问

UDP套接字绑定端口0时为什么父进程可以打印出内核分配的端口号而子进程不可以?

以下是我用来测试父子进程创建UDP套接字并绑定0端口并打印套接字地址和端口号的程序,其中getsockname只是用来打印出端口号和IP地址。我分别在父子进程都创建了UDP套接字并绑定0端口(由内核分配端口号),但输出结果是只有在父进程才能输出端口号和IP地址,子进程输出的端口号和IP地址都是0,不知为何,求解答!

#include "unp.h"

void getsockpeername(int sockfd)
{
struct sockaddr_in IPclient,IPserver;
socklen_t len_cli,len_srv;
char str1[20],str2[20];
bzero(&IPclient,sizeof(IPclient));
bzero(&IPserver,sizeof(IPserver));

if(getsockname(sockfd,(SA*)&IPclient,&len_cli)<0)
{
    perror("get socket name error\n");
}
int IPclient_port=ntohs(IPclient.sin_port);
printf("The server port number generated by kernel is %d\n",IPclient_port);
Inet_ntop(AF_INET,&IPclient.sin_addr,str1,sizeof(str1));
printf("The IPserver is %s\n",str1);

}

int main(int argc, char **argv)
{
pid_t pid;
int new_sockfd1;
new_sockfd1 = socket(AF_INET, SOCK_DGRAM, 0);

struct sockaddr_in srvaddr;
unsigned long ipserver = 0x82f501b6;
bzero(&srvaddr,sizeof(srvaddr));
srvaddr.sin_family = AF_INET;
srvaddr.sin_addr.s_addr = ipserver;
srvaddr.sin_port = htons(0);

bind(new_sockfd1, (SA *)&srvaddr, sizeof(srvaddr));

getsockpeername(new_sockfd1);
if((pid=fork())<0)
{
    perror("fork failed\n");
    exit(1);
}
if(pid==0)
{
        int new_sockfd2;
        new_sockfd2 = socket(AF_INET, SOCK_DGRAM, 0);

        struct sockaddr_in srvaddr1;
        unsigned long ipserver = 0x82f501b6;
        bzero(&srvaddr1,sizeof(srvaddr1));
        srvaddr1.sin_family = AF_INET;
        srvaddr1.sin_addr.s_addr = ipserver;
        srvaddr1.sin_port = htons(0);

        bind(new_sockfd2, (SA *)&srvaddr1, sizeof(srvaddr1));

        getsockpeername(new_sockfd2);

}
return 0;

}

1个回答

gqtcgq
gqtcgq   2015.04.27 13:07

父子进程绑定同样的地址,不设置SO_REUSEADDR的话,子进程的绑定肯定会失败,测试一下子进程中的bind函数的返回值。

gqtcgq
gqtcgq 错了,请无视改答案
2 年多之前 回复
Csdn user default icon
上传中...
上传图片
插入图片
准确详细的回答,更有利于被提问者采纳,从而获得C币。复制、灌水、广告等回答会被删除,是时候展现真正的技术了!