Linux下的UDP通信

由于UDP通信不需要事先建立连接,因此不需要TCP中的connect函数。



服务器端的步骤如下:

1. socket:      建立一个socket

2. bind:          将这个socket绑定在某个端口上(AF_INET)

3. recvfrom:  如果没有客户端发起请求,则会阻塞在这个函数里

4. close:        通信完成后关闭socket



客户端的步骤如下:

1. socket:      建立一个socket

2. sendto:     相服务器的某个端口发起请求(AF_INET)

3. close:        通信完成后关闭socket



可以看到,和TCP相比,步骤少了一些。


这里我们用到了两个新的函数:

int recvfrom(int sockfd, void * buf, size_t len, int flags, struct sockaddr * src_addr, socklen_t * addrlen);

int sendto(int sockfd, const void * buf, size_t len, int flags, const struct sockaddr * dest_addr, socklen_t addrlen);


recvfrom用于接收数据,sendto用于发送数据


recvfrom:

socket:socket套接字

buf:接收到的数据的存放位置

flags:一般情况下为0

src_addr:接收的源地址

addrlen:地址长度



sendto:

socket:socket套接字

buf:要发送的数据的起始地址

flags:一般情况下为0

dest_addr:发送到的目的地址

addrlen:地址长度



还是先上代码:

Makefile:

  1. all: server.c client.c  
  2.     gcc -Wall client.c -o client  
  3.     gcc -Wall server.c -o server  
  4.   
  5. clean:  
  6.     rm -rf *.o client server  
all: server.c client.c
	gcc -Wall client.c -o client
	gcc -Wall server.c -o server

clean:
	rm -rf *.o client server


server:

  1. #include <stdio.h>   
  2. #include <sys/types.h>   
  3. #include <sys/socket.h>   
  4. #include <netinet/in.h>   
  5. #include <unistd.h>   
  6. #include <errno.h>   
  7. #include <string.h>   
  8. #include <stdlib.h>   
  9.   
  10.   
  11. #define SERV_PORT   8000   
  12.   
  13.   
  14. int main()  
  15. {  
  16.   /* socket文件描述符 */  
  17.   int sock_fd;  
  18.   
  19.   /* 建立udp socket */  
  20.   sock_fd = socket(AF_INET, SOCK_DGRAM, 0);  
  21.   if(sock_fd < 0)  
  22.   {  
  23.     perror("socket");  
  24.     exit(1);  
  25.   }  
  26.   
  27.   /* 设置address */  
  28.   struct sockaddr_in addr_serv;  
  29.   int len;  
  30.   memset(&addr_serv, 0, sizeof(struct sockaddr_in));  
  31.   addr_serv.sin_family = AF_INET;  
  32.   addr_serv.sin_port = htons(SERV_PORT);  
  33.   /* INADDR_ANY表示不管是哪个网卡接收到数据,只要目的端口是SERV_PORT,就会被该应用程序接收到 */  
  34.   addr_serv.sin_addr.s_addr = htonl(INADDR_ANY);  
  35.   len = sizeof(addr_serv);  
  36.     
  37.   /* 绑定socket */  
  38.   if(bind(sock_fd, (struct sockaddr *)&addr_serv, sizeof(addr_serv)) < 0)  
  39.   {  
  40.     perror("bind error:");  
  41.     exit(1);  
  42.   }  
  43.   
  44.     
  45.   int recv_num;  
  46.   int send_num;  
  47.   char send_buf[20] = "i am server!";  
  48.   char recv_buf[20];  
  49.   struct sockaddr_in addr_client;  
  50.   
  51.   while(1)  
  52.   {  
  53.     printf("server wait:\n");  
  54.       
  55.     recv_num = recvfrom(sock_fd, recv_buf, sizeof(recv_buf), 0, (struct sockaddr *)&addr_client, (socklen_t *)&len);  
  56.       
  57.     if(recv_num < 0)  
  58.     {  
  59.       perror("recvfrom error:");  
  60.       exit(1);  
  61.     }  
  62.   
  63.     recv_buf[recv_num] = '\0';  
  64.     printf("server receive %d bytes: %s\n", recv_num, recv_buf);  
  65.   
  66.     send_num = sendto(sock_fd, send_buf, recv_num, 0, (struct sockaddr *)&addr_client, len);  
  67.       
  68.     if(send_num < 0)  
  69.     {  
  70.       perror("sendto error:");  
  71.       exit(1);  
  72.     }  
  73.   }  
  74.     
  75.   close(sock_fd);  
  76.     
  77.   return 0;  
  78. }  
#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <unistd.h>
#include <errno.h>
#include <string.h>
#include <stdlib.h>


#define SERV_PORT   8000


int main()
{
  /* socket文件描述符 */
  int sock_fd;

  /* 建立udp socket */
  sock_fd = socket(AF_INET, SOCK_DGRAM, 0);
  if(sock_fd < 0)
  {
    perror("socket");
    exit(1);
  }

  /* 设置address */
  struct sockaddr_in addr_serv;
  int len;
  memset(&addr_serv, 0, sizeof(struct sockaddr_in));
  addr_serv.sin_family = AF_INET;
  addr_serv.sin_port = htons(SERV_PORT);
  /* INADDR_ANY表示不管是哪个网卡接收到数据,只要目的端口是SERV_PORT,就会被该应用程序接收到 */
  addr_serv.sin_addr.s_addr = htonl(INADDR_ANY);
  len = sizeof(addr_serv);
  
  /* 绑定socket */
  if(bind(sock_fd, (struct sockaddr *)&addr_serv, sizeof(addr_serv)) < 0)
  {
    perror("bind error:");
    exit(1);
  }

  
  int recv_num;
  int send_num;
  char send_buf[20] = "i am server!";
  char recv_buf[20];
  struct sockaddr_in addr_client;

  while(1)
  {
    printf("server wait:\n");
    
    recv_num = recvfrom(sock_fd, recv_buf, sizeof(recv_buf), 0, (struct sockaddr *)&addr_client, (socklen_t *)&len);
    
    if(recv_num < 0)
    {
      perror("recvfrom error:");
      exit(1);
    }

    recv_buf[recv_num] = '\0';
    printf("server receive %d bytes: %s\n", recv_num, recv_buf);

    send_num = sendto(sock_fd, send_buf, recv_num, 0, (struct sockaddr *)&addr_client, len);
    
    if(send_num < 0)
    {
      perror("sendto error:");
      exit(1);
    }
  }
  
  close(sock_fd);
  
  return 0;
}


client:

  1. #include <stdio.h>   
  2. #include <string.h>   
  3. #include <errno.h>   
  4. #include <stdlib.h>   
  5. #include <unistd.h>   
  6. #include <sys/types.h>   
  7. #include <sys/socket.h>   
  8. #include <netinet/in.h>   
  9. #include <arpa/inet.h>   
  10.    
  11.   
  12. #define DEST_PORT 8000   
  13. #define DSET_IP_ADDRESS  "127.0.0.1"   
  14.    
  15.   
  16. int main()  
  17. {  
  18.   /* socket文件描述符 */  
  19.   int sock_fd;  
  20.   
  21.   /* 建立udp socket */  
  22.   sock_fd = socket(AF_INET, SOCK_DGRAM, 0);  
  23.   if(sock_fd < 0)  
  24.   {  
  25.     perror("socket");  
  26.     exit(1);  
  27.   }  
  28.     
  29.   /* 设置address */  
  30.   struct sockaddr_in addr_serv;  
  31.   int len;  
  32.   memset(&addr_serv, 0, sizeof(addr_serv));  
  33.   addr_serv.sin_family = AF_INET;  
  34.   addr_serv.sin_addr.s_addr = inet_addr(DSET_IP_ADDRESS);  
  35.   addr_serv.sin_port = htons(DEST_PORT);  
  36.   len = sizeof(addr_serv);  
  37.   
  38.     
  39.   int send_num;  
  40.   int recv_num;  
  41.   char send_buf[20] = "hey, who are you?";  
  42.   char recv_buf[20];  
  43.       
  44.   printf("client send: %s\n", send_buf);  
  45.     
  46.   send_num = sendto(sock_fd, send_buf, strlen(send_buf), 0, (struct sockaddr *)&addr_serv, len);  
  47.     
  48.   if(send_num < 0)  
  49.   {  
  50.     perror("sendto error:");  
  51.     exit(1);  
  52.   }  
  53.     
  54.   recv_num = recvfrom(sock_fd, recv_buf, sizeof(recv_buf), 0, (struct sockaddr *)&addr_serv, (socklen_t *)&len);  
  55.     
  56.   if(recv_num < 0)  
  57.   {  
  58.     perror("recvfrom error:");  
  59.     exit(1);  
  60.   }  
  61.     
  62.   recv_buf[recv_num] = '\0';  
  63.   printf("client receive %d bytes: %s\n", recv_num, recv_buf);  
  64.     
  65.   close(sock_fd);  
  66.     
  67.   return 0;  
  68. }  
#include <stdio.h>
#include <string.h>
#include <errno.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
 

#define DEST_PORT 8000
#define DSET_IP_ADDRESS  "127.0.0.1"
 

int main()
{
  /* socket文件描述符 */
  int sock_fd;

  /* 建立udp socket */
  sock_fd = socket(AF_INET, SOCK_DGRAM, 0);
  if(sock_fd < 0)
  {
    perror("socket");
    exit(1);
  }
  
  /* 设置address */
  struct sockaddr_in addr_serv;
  int len;
  memset(&addr_serv, 0, sizeof(addr_serv));
  addr_serv.sin_family = AF_INET;
  addr_serv.sin_addr.s_addr = inet_addr(DSET_IP_ADDRESS);
  addr_serv.sin_port = htons(DEST_PORT);
  len = sizeof(addr_serv);

  
  int send_num;
  int recv_num;
  char send_buf[20] = "hey, who are you?";
  char recv_buf[20];
    
  printf("client send: %s\n", send_buf);
  
  send_num = sendto(sock_fd, send_buf, strlen(send_buf), 0, (struct sockaddr *)&addr_serv, len);
  
  if(send_num < 0)
  {
    perror("sendto error:");
    exit(1);
  }
  
  recv_num = recvfrom(sock_fd, recv_buf, sizeof(recv_buf), 0, (struct sockaddr *)&addr_serv, (socklen_t *)&len);
  
  if(recv_num < 0)
  {
    perror("recvfrom error:");
    exit(1);
  }
  
  recv_buf[recv_num] = '\0';
  printf("client receive %d bytes: %s\n", recv_num, recv_buf);
  
  close(sock_fd);
  
  return 0;
}



程序的运行截图如下:




client向服务器发送了“hey, who are you?”的字符串,server返回"i am server!"的字符串。



最后,我把上面的这个程序也上传上来了:

http://download.csdn.net/detail/htttw/4297666



完成!

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值