UDP客戶端不用綁定嗎IP和端口?

  書上都是這麼說的,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>
#include<stdlib.h>
#include<string.h>
#include<sys/types.h>
#include<sys/socket.h>
#include<errno.h>
#include<arpa/inet.h>
#include<netinet/in.h>
#define  SERADDR "127.0.0.1"
int main(int ar, char**argv) {
        int fd1, fd2;
        char *s;
        char ss[20];
        char port[7];
        int server_ip;
        char buf[1024];
        int len=sizeof(struct sockaddr);
        int sin_size = sizeof(struct sockaddr_in);
        struct sockaddr_in local_addr,other,other1;
        if (-1 == (fd1 = socket(AF_INET, SOCK_DGRAM, 0))) {
                perror("fail to socket\n");
                exit(0);
        }
        memset(buf,0,1024);
        memset(&local_addr,0,sizeof(struct sockaddr));
        local_addr.sin_family = AF_INET;
        local_addr.sin_port = htons(50126);

        inet_pton(AF_INET, "10.10.1.103", (void*) &server_ip);
        local_addr.sin_addr.s_addr = server_ip;


        if (bind(fd1, (struct sockaddr*) &local_addr, sizeof(struct sockaddr))
                        < 0) {
                fprintf(stderr, "error:bind() error!\n");
    exit(-1);
        }


        recvfrom(fd1,buf,1023,0,(struct sockaddr*)&other,&len);
        in_port_t temport=ntohs(other.sin_port);
        sprintf(port,"%u",temport);
        printf("A,port =%s\n",port);
        printf("A ,client give me:%s\n",buf);
        memset(buf,0,sizeof(buf));

        recvfrom(fd1,buf,1023,0,(struct sockaddr*)&other1,&len);
        printf("B ,cLient give me:%s\n",buf);
        in_port_t temport1=ntohs(other1.sin_port);
        memset(port,0,sizeof(port));
        sprintf(port,"%u",temport1);


        printf("B,port=%s\n",port);
        //printf("hhhhhh\n");
        sendto(fd1,buf,strlen(buf),0,(struct sockaddr*)&other,sizeof(struct sockaddr_in));
        sendto(fd1,"OKOKOK",6,0,(struct sockaddr*)&other1,sizeof(struct sockaddr_in));

      
        return 0;

}
相關文章
相關標籤/搜索