书上都是这么说的,UDP客户端不用绑定IP和端口,操做系统会给它自动分配端口。。。。服务器
可是虽然没有显示绑定,可是操做系统却彷佛作了些隐蔽的事情。socket
首先,在客户端,fd = socket(AF_INET, SOCK_DGRAM, 0),而后就想在此fd下进行recvfrom是收不到对方(假设对方就是服务器吧)的消息是办不到的,其实想一想也很容易明白,这是fd未和任何端口、 IP产生关联要是这样都能收到消息,那真要乱套了。想要在没绑定的状况下受到服务器发来的消息,首先客户端得经过fd描述符首先向服务器发信息,而后这时 在fd下进行阻塞recvfrom就能收到消息了,若是再在客户端上fd 1= socket(AF_INET, SOCK_DGRAM, 0),想在fd1 上进行recvfrom依然收不到消息,由于fd和服务器同过信,但fd1没有,因此fd1收不到,可是从fd1向服务器发消息没问题!所一总结一下就 是,只有当已经过fd向服务器发送了消息时(而且已经发通了),才能在fd处收到服务器发回来的消息,可是向服务器发送消息就不须要。因此说操做系统在此 作了些隐蔽的事情,当fd首先向服务器发消息时客户端自动选折IP和一个PORT与该fd关联了起来,(我以为至关于背后仍是绑定了同样)。然后面建立的 fd1和以前的fd他们出客户端的PORT是不一样的(我在服务器端检测了一下),因此经过fd向服务器发了消息但想在新创建的fd1下去recvfrom 收不到消息。spa
另外,只能对一个socket描述符绑定一次,不能绑定屡次,除非前面已经将该描述符close了。操作系统
反过来一个端口也只能被绑定到同一个socket描述符上,除非他们使用的不一样的协议。server
下面有一些验证代码:ip
client.cget
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <strings.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h>
#define PORT 50126
#define MAXDATASIZE 100
int main(int argc, char *argv[])
{
int fd1, numbytes;
char recvbuf[MAXDATASIZE];
char sendbuf[MAXDATASIZE];
struct sockaddr_in server,self,rep;
if ((fd1=socket(AF_INET, SOCK_DGRAM, 0))==-1){
printf("socket() error\n");
exit(1);
}
int server_ip1;
input
bzero(&self,sizeof(self));
self.sin_family = AF_INET;
self.sin_port = htons(PORT);
inet_pton(AF_INET, "10.10.1.103", (void*) &server_ip1);
server.sin_addr.s_addr = server_ip1;
bind(fd1,(struct sockaddr*)&self,sizeof(self));
int server_ip;
bzero(&server,sizeof(server));
server.sin_family = AF_INET;
server.sin_port = htons(PORT);
inet_pton(AF_INET, "10.10.1.103", (void*) &server_ip);
server.sin_addr.s_addr = server_ip;
socklen_t len;
len=sizeof(struct sockaddr_in);
printf("input message:");
fgets(sendbuf,40,stdin);
sendto(fd1,sendbuf,strlen(sendbuf),0,(struct sockaddr *)&server,len);
printf("send already\n");
int fd2=socket(AF_INET,SOCK_DGRAM,0);
int i=bind(fd2,(struct sockaddr*)&self,sizeof(self));
printf("%d\n",i);
memset(sendbuf,0,sizeof(sendbuf));
fgets(sendbuf,sizeof(sendbuf),stdin);
sendto(fd2,sendbuf,strlen(sendbuf),0,(struct sockaddr *)&server,len);
memset(recvbuf,0,sizeof(recvbuf));
recvfrom(fd1,recvbuf,strlen(sendbuf),0,(struct sockaddr * ) &rep,&len);
printf("A server give me:%s\n",recvbuf );
recvfrom(fd2,recvbuf,strlen(sendbuf),0,(struct sockaddr * ) &rep,&len);
printf("fd2 server give me:%s\n",recvbuf);
return 0;
}
~ string
service.cit
#include<stdio.h>