UDP通信问题小结

最近在看一个关于UDP通信的实例的程序,从中对UDP通信有了一些不一样的认识,之前对udp与tcp的区别只是停留在下面这样宏观的认知上
1、TCP面向连接(如打电话要先拨号建立连接)。
UDP是无连接的,即发送数据之前不需要建立连接。
2、安全方面的区别TCP提供可靠的服务,通过TCP连接传送的数据,无差错,不丢失,不重复,且按序到达。UDP尽最大努力交付,即不保证可靠交付。

从上面的区别来看,在一般的编程当中当然是tcp更加可靠一点,而我在实际中也是这样做的,写过的网络程序中几乎所有的都是TCP协议来传输数据的,但是在写程序的过程中也遇到一些头疼的事情,
1、tcp的面向连接的,那么一旦当连接异常终止的时候就会有一些意向不到的事情发生,而我也是经常在此花费巨大的代价去解决这个问题。
2、tcp是点对点的通信,当需要建立并发服务器的时候我经常使用多线程的机制来完成,这无形中增加了性能的损耗(这一点不重要哈!)。

我在最近这段时间接触UDP通信中,发现了一些它的特点
1、udp通信不存在上面我所描述的连接问题,因为它毕竟是无连接嘛(好像是一句废话),不过这样就不需要花费时间来处理这个问题了,很爽是不是。
2、在写tcp通信的时候我们都知道里边有server端和client端的区分,也就是我们常说的C/S架构,但是在udp中这样的概念好像很模糊,或者说根本不存在,先看一个小例子吧

server.c

#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <string.h>
#include <arpa/inet.h>
typedef struct sockaddr* saddrp;
int main(int argc, char const *argv[])
{
     //创建socket
     int sockfd = socket(AF_INET,SOCK_DGRAM,0);
     if (0 > sockfd)
     {
          perror("sockfd");
          return -1;
     }
     // server端的地址信息
     struct sockaddr_in addr = {};
     addr.sin_family = AF_INET;
     addr.sin_port = htons(5577);				//端口号
     addr.sin_addr.s_addr = inet_addr("127.0.0.1"); //我的ip地址
     // 将地址信息绑定到socket上
     int ret = bind(sockfd,(saddrp)&addr,sizeof(addr));
     if (0 > ret)
     {
          perror("bind");
          return -1;
     }
     // client端的地址信息
     socklen_t addr_len = sizeof(struct sockaddr_in);
     struct sockaddr_in addr_i = {};
     addr_i.sin_family = AF_INET;
     addr_i.sin_port = htons(7755);
     addr_i.sin_addr.s_addr = inet_addr("127.0.0.1");
     while(1){
         char buf[255] = {};
         recvfrom(sockfd,buf,sizeof(buf),0,(saddrp)&addr,&addr_len);		// 使用server端的地址信息接收信息
         printf("Recv:%s\n",buf);
         if(0 == strcmp(buf,"q")) break;
         sendto(sockfd,buf,strlen(buf)+1,0,(saddrp)&addr_i,addr_len);		// 使用client端的地址信息发送信息
         printf("send ok!\n"); 
      }  
   //关闭socket对象
   close(sockfd);
   return 0;
   }

client.c

#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <string.h>
#include <arpa/inet.h>
#include <unistd.h>
typedef struct sockaddr* saddrp;
int main(int argc, char const *argv[])
{ 
    //  创建socket
     int sockfd = socket(AF_INET,SOCK_DGRAM,0);
     if (0 > sockfd)
     {
          perror("socket");
          return -1;
     }
     //  client 端的地址信息
     struct sockaddr_in addr_i = {};
     addr_i.sin_family = AF_INET;
     addr_i.sin_port = htons(7755);
     addr_i.sin_addr.s_addr = inet_addr("127.0.0.1");
     // 绑定
     int ret = bind(sockfd,(saddrp)&addr_i,sizeof(addr_i));
     if (0 > ret)
     {
          perror("bind");
          return -1;
     }
     // server端的地址信息
     struct sockaddr_in addr = {};
     addr.sin_family = AF_INET;
     addr.sin_port = htons(5577);
     addr.sin_addr.s_addr = inet_addr("127.0.0.1");
     socklen_t addr_len = sizeof(struct sockaddr_in);
     while(1)
     {
 	char buf[255] = {};
 	char buf1[255] = {};
 	printf("Please input the return value:");
   	fgets(buf,255,stdin);
 	buf[strlen(buf) - 1] = '\0';
   	sendto(sockfd,buf,strlen(buf)+1,0,(saddrp)&addr,addr_len);			// 发
   	if (0 == strcmp(buf,"q")) break;
         recvfrom(sockfd,buf1,sizeof(buf1),0,(saddrp)&addr_i,&addr_len);	       // 收
        printf("Recv:%s\n",buf);
    }
     close(sockfd);
     return 0;
  }

测试结果:和预想的一样,可以实现数据的传输
在这里插入图片描述
虽然我在这里的文件命名为server.c和client.c,但是可以看到两个文件的程序架构几乎是一模一样的,也就是说这样的server和client的区分只是我们认为的区分罢了,udp中完全是根据socket和自己以及对方的地址信息来完成数据的收发的。
总结:tcp和udp还是有本质上的区别的,它们应用的常用也是各不相同,说了这么多,当然在实际的编写程序中还是要根据自己的需求来选择通信协议的,毕竟各有千秋嘛,这里我也不是说哪个好哪个不好,这是记录一下我的一些小发现吧,就当娱乐来看吧。

发布了33 篇原创文章 · 获赞 2 · 访问量 1034

猜你喜欢

转载自blog.csdn.net/weixin_41791581/article/details/102620363