计算机网络socket编程之UDP

>UDP是一种不面向连接的不可靠的网络传输协议

  UDP协议前面大部分和TCP协议差不多,只是他的客户程序不需要连接,而是直接发送数据。

>sendto() 和recvfrom() 函数

使用这两个函数,则数据会在没有建立过任何连接的网络上传输。正好可以在进行无连接的UDP 通讯时使用的。因为数据报套接字无法对远程主机进行连接,想想我们在发送数据前需要知道些什么呢?是远程主机的IP 地址和端口!

下面是sendto()函数和recvfrom()函数的声明:

#include

#include

int sendto(int sockfd, const void *msg, int len, unsigned int flags,const struct sockaddr *to, int tolen);

和你所看到的一样,这个函数和send()函数基本一致。

   sockfd 是代表你与远程程序连接的套接字描述符。

   msg 是一个指针,指向你想发送的信息的地址。

   len 是你想发送信息的长度。

   flags 发送标记。一般都设为0。(你可以查看send 的man pages 来获得其他的参数值并且明白各个参数所代表的含义)

   to 是一个指向struct sockaddr 结构的指针,里面包含了远程主机的IP 地址和端口数据。

   tolen 只是指出了struct sockaddr 在内存中的大小sizeof(struct sockaddr)。和send()一样,sendto()返回它所真正发送的字节数(当然也和send()一样,它所真正发送的字节数可能小于你所给它的数据的字节数)。当它发生错误的时候,也是返回 –1 ,同时全局变量errno 存储了错误代码。同样的,recv()函数和recvfrom()函数也基本一致。

   recvfrom()的声明为:

   #include

   #include

   int recvfrom(int sockfd, void *buf, int len, unsigned int flags

   struct sockaddr *from, int *fromlen);

其参数含义如下:

   sockfd 是你要读取数据的套接字描述符。

   buf 是一个指针,指向你能存储数据的内存缓存区域。

   len 是缓存区的最大尺寸。

   flags 是recv() 函数的一个标志,一般都为0 (具体的其他数值和含义请参考recv()的man pages)。

   from 是一个本地指针,指向一个struct sockaddr 的结构(里面存有源IP 地址和端口数).

   fromlen 是一个指向一个int 型数据的指针,它的大小应该是sizeof ( structsockaddr).当函数返回的时候formlen 指向的数据是form 指向的struct sockaddr 的实际大小.

recvfrom() 返回它接收到的字节数,如果发生了错误,它就返回-1

>具体程序 

  server.c

  1 #include                                                           
  2 #include
  3 #include
  4 #include
  5 #include
  6 #include
  7 #include
  8 #include
  9 
 10 
 11 static void usage(const char* proc)
 12 {
 13     printf("usage:%s [ip] [port]\n", proc);
 14 }
 15 
 16 int main(int argc,char* argv[])
 17 {
 18    if(argc!=3)
 19    {
 20        usage(argv[0]);
 21        exit(1);
 22    }
23 
 24    int sock=socket(AF_INET,SOCK_DGRAM,0);
 25    if(sock < 0){
 26        perror("sock");
 27        exit(2);
 28    }
 29    struct sockaddr_in local;
 30    local.sin_family=AF_INET;
 31    local.sin_addr.s_addr=inet_addr(argv[1]);
 32    local.sin_port=htons(atoi(argv[2]));
 33 
 34 //   int opt=1;
 35   // setsockopt(sock,SOL_SOCKET,SO_REUSEADDR,&opt,sizeof(opt));
 36 
 37    if(bind(sock,(struct sockaddr*)&local,sizeof(local))<0){
 38      perror("bind");
 39      return 3;
 40    } 
41 
 42    int done=0;
 43    struct sockaddr_in peer;
 44    socklen_t len=sizeof(peer);
 45    char buf[1024];
 46 
 47    while(!done){
 48       memset(buf,'\0',sizeof(buf));
 49       recvfrom(sock,buf,sizeof(buf),0,(struct sockaddr*)&peer,&len);
 50       printf("########################\n");
 51       printf("get a client,socket->%s:%d\n",inet_ntoa(peer.sin_addr),ntohs(p    eer.sin_port));
 52 
 53       printf("#client:%s,echo client!\n",buf);
 54       printf("#######################\n");
 55       sendto(sock,buf,sizeof(buf),0,(struct sockaddr*)&peer,len);
 56    } 
 57    return 0;
 58 }                                                                             

client.c

 1 #include                                                           
  2 #include
  3 #include
  4 #include
  5 #include
  6 #include
  7 #include
  8 
  9 static void usage(const char* proc)
 10 {
 11    printf("usage:%s [remote_ip] [remote_port]\n",proc);
 12 }
 13 
 14 int main(int argc,char* argv[])
 15 {
 16     if(argc!=3){
 17         usage(argv[0]);
 18         return 1;
 19     }
 20 
 21     int sock=socket(AF_INET,SOCK_DGRAM,0);
 22     if(sock<0){
23         perror("socket");
 24         return 2;
 25     }                                                                       
 26 
 27     struct sockaddr_in remote;
 28     remote.sin_family=AF_INET;
 29     remote.sin_addr.s_addr=inet_addr(argv[1]);
 30     remote.sin_port=htons(atoi(argv[2]));
 31 
 32     int done=0;
 33     char buf[1024];
 34     struct sockaddr_in peer;
 35     socklen_t len=sizeof(peer);
 36 
 37     while(!done){
 38         printf("Please Enter:");
 39         fflush(stdout);
 40         ssize_t _s=read(0,buf,sizeof(buf)-1);
 41         if(_s > 0){
 42             buf[_s]='\0';
43         sendto(sock,buf,sizeof(buf),0,(struct sockaddr*)&remote,sizeof(remot    e));
 44         memset(buf,'\0',sizeof(buf));
 45         recvfrom(sock,buf,sizeof(buf),0,(struct sockaddr*)&peer,&len);
 46         printf("server echo %s,socket>%s:%d\n",buf,inet_ntoa(peer.sin_addr),    ntohs(peer.sin_port));
 47     }
 48     }
 49     return 0;
 50 }


结果:

计算机网络socket编程之UDP_第1张图片计算机网络socket编程之UDP_第2张图片

你可能感兴趣的:(计算机网络socket编程之UDP)