基于udp协议的网络程序

author author     2022-11-05     641

关键词:

下图是基于UDP协议的客户端/服务器程序的一般流程:

图1.1 UDP协议通信流程

技术分享图片

UDP套接口是无连接的、不可靠的数据报协议;

既然他不可靠为什么还要用呢?其一:当应用程序使用广播或多播时只能使用UDP协议;其二:由于他是无连接的,所以速度快。因为UDP套接口是无连接的,如果一方的数据报丢失,那另一方将无限等待,解决办法是设置一个超时。

建立UDP套接口时socket函数的第二个参数应该是SOCK_DGRAM,说明是建立一个UDP套接口;由于UDP是无连接的,所以服务器端并不需要listen或accept函数。

使用UDP套接字编程可以实现基于TCP/IP协议的面向无连接的通信,它分为服务器端和客户端两部分,其主要实现过程如图1.1所示。

下面介绍UDP网络编程的详细函数和过程:

 1、socket函数:为了执行网络输入输出,一个进程必须做的第一件事就是调用socket函数获得一个文件描述符。

-----------------------------------------------------------------
 #include <sys/socket.h>
 int socket(int family,int type,int protocol);    
      返回:非负描述字---成功   -1---失败
 -----------------------------------------------------------------

第一个参数指明了协议簇,目前支持5种协议簇,最常用的有AF_INET(IPv4协议)和AF_INET6(IPv6协议);第二个参数指明套接口类型,有三种类型可选:SOCK_STREAM(字节流套接口)、SOCK_DGRAM(数据报套接口)和SOCK_RAW(原始套接口);如果套接口类型不是原始套接口,那么第三个参数就为0。

2、bind函数:为套接口分配一个本地IP和协议端口,对于网际协议,协议地址是32位IPv4地址或128位IPv6地址与16位的TCP或UDP端口号的组合;如指定端口为0,调用bind时内核将选择一个临时端口,如果指定一个通配IP地址,则要等到建立连接后内核才选择一个本地IP地址。

-------------------------------------------------------------------
#include <sys/socket.h>  
 int bind(int sockfd, const struct sockaddr * server, socklen_t addrlen);
 返回:0---成功   -1---失败 
 -------------------------------------------------------------------

  第一个参数是socket函数返回的套接口描述字;第二和第第三个参数分别是一个指向特定于协议的地址结构的指针和该地址结构的长度。

3、recvfrom函数:UDP使用recvfrom()函数接收数据,他类似于标准的read(),但是在recvfrom()函数中要指明目的地址。

-------------------------------------------------------------------
#include <sys/types.h>  
#include <sys/socket.h>  
ssize_t recvfrom(int sockfd, void *buf, size_t len, int flags, struct sockaddr * from, size_t *addrlen);
 返回接收到数据的长度---成功   -1---失败 
 -------------------------------------------------------------------

  前三个参数等同于函数read()的前三个参数,flags参数是传输控制标志。最后两个参数类似于accept的最后两个参数。

4、sendto函数:UDP使用sendto()函数发送数据,他类似于标准的write(),但是在sendto()函数中要指明目的地址。

-------------------------------------------------------------------
#include <sys/types.h>  
#include <sys/socket.h>  
ssize_t sendto(int sockfd, const void *buf, size_t len, int flags, const struct sockaddr * to, int addrlen);
 返回发送数据的长度---成功   -1---失败 
 -------------------------------------------------------------------

  前三个参数等同于函数read()的前三个参数,flags参数是传输控制标志。参数to指明数据将发往的协议地址,他的大小由addrlen参数来指定。

server.c程序源码:

  #include <stdio.h>                                                                                                                 
  #include <sys/socket.h>
  #include <stdlib.h>
  #include <netinet/in.h>
  #include <unistd.h>
  #include <sys/types.h>
  #include <string.h>
 
  #define _MAXLINE_ 80
  #define _SERV_PORT_  8000
  
  int main()
  
      struct sockaddr_in server_addr,client_addr;
      socklen_t cliaddr_len;
      int sockfd;
      char buf[_MAXLINE_];
      char str[INET_ADDRSTRLEN];
      int i, n;
  
      sockfd = socket(AF_INET, SOCK_DGRAM, 0);
      if(sockfd < 0)
          printf("create socket error!...\n");
          return -1;
      
  
      bzero(&server_addr,sizeof(server_addr));
      server_addr.sin_family = AF_INET;
      server_addr.sin_addr.s_addr = htonl(INADDR_ANY);
      server_addr.sin_port = htons(_SERV_PORT_);
  
      if(bind(sockfd,(struct sockaddr*)&server_addr,sizeof(server_addr)) < 0)
          printf("bind error!...");
          close(sockfd);
          return 1;
      
  
      printf("Accepting connections ...\n");
      while(1)
          cliaddr_len = sizeof(client_addr);
          //n = recvfrom(sockfd, buf, _MAXLINE_, 0,(struct sockaddr *)&client_addr, &cliaddr_len);
          n = recvfrom(sockfd, buf, _MAXLINE_, 0,(struct sockaddr *)&client_addr, &cliaddr_len);
          if(n == -1)
              printf("recvfrom error...\n");
              exit(1);
          
          printf("received from %s at PORT %d\n",inet_ntop(AF_INET, &client_addr.sin_addr, 
                  str,sizeof(str)),ntohs(client_addr.sin_port));
  
          for(i = 0; i < n; i++)
              buf[i] = toupper(buf[i]);
          
          n = sendto(sockfd, buf, n, 0, (struct sockaddr *)&client_addr, sizeof(client_addr));
          if(n == -1)
              printf("sendto error...\n");
          
      
      return 0;
  

UDP客户端程序设计

client.c程序源码:

   #include <stdio.h>                                                                                                                                       
   #include <string.h>
   #include <unistd.h>
   #include <netinet/in.h>
   
   #define _MAXLINE_ 80
   #define _SERV_PORT_  8000
   
   int main(int argc, int* argv[])
  
      struct sockaddr_in servaddr;
      int sockfd, n;
      char buf[_MAXLINE_];
      char str[INET_ADDRSTRLEN];
      socklen_t servaddr_len;
  
      sockfd = socket(AF_INET, SOCK_DGRAM, 0);

      bzero(&servaddr, sizeof(servaddr));
      servaddr.sin_family = AF_INET;
      inet_pton(AF_INET, "127.0.0.1", &servaddr.sin_addr);
      servaddr.sin_port = htons(_SERV_PORT_);
  
      while(fgets(buf, _MAXLINE_, stdin)!= NULL)
          n = sendto(sockfd, buf, strlen(buf), 0, (struct sockaddr *)                  &servaddr, sizeof(servaddr));
          if(n == -1)
              printf("sendto error\n");
          
          n = recvfrom(sockfd, buf, _MAXLINE_, 0, NULL, 0);
          if(n == -1)
              printf("recvfrom error\n");
          
          write(STDOUT_FILENO, buf, n);
      
  
      close(sockfd);
      return 0;
  


运行展示,client发送小写字母,server收到之后进行大小写转换,发回到client,结果如下:

技术分享图片


网络--udp知识(代码片段)

...DP的功能比较弱,仅对IP层进行简单的接口包装,应用程序可基于UDP;而TCP可实现的功能,在应用程序层也可实现,那么即可绕开TCP,直接基于IP编程.TCP对比UDP协议TCPUDP是否可靠可靠不可靠[大概率丢包,乱序,重复]协议流式协议报文协议形... 查看详情

java中基于udp协议的的网络编程(基础篇)

...算机网络的基础,我们不难理解,在java中,网络编程是基于网络传输协议的。  java网络编程,可以是基于 查看详情

《网络编程》第4节:基于udp协议的网络编程

...发送、接收数据报的对象。Java提供了DatagramSocket对象作为基于UDP协议的Socket,而使用DatagramPacket代表DatagramSocket发送、接收的数据报。本小节将详细讲解基于UDP协议的网络编程 查看详情

基于udp协议的网络编程

...ket只是发送、接收数据报的对象。Java使用DatagramSocket代表基于UDP协议的Socket,DatagramSocket本身只是码头,不维护状态,不能产生IO流,它的唯一作用就是接收和发送数据报。Java使用DatagramPacket来代表数据报,Dat 查看详情

网络编程:基于udp协议的socket

udp是无链接的,启动服务之后可以直接接受消息,不需要提前建立链接 UDP协议的通信优势:       允许一个服务器同时和多个客户端通信,TCP不行  查看详情

网络编程的常识基于tcp协议的编程模型tcp协议和udp协议的比较基于udp协议的编程模型

1.网络编程的常识目前主流的网络通讯软件有:微信、QQ、YY、陌陌、探探、飞信、阿里旺旺、...在吗?1.1七层网络模型(熟悉)为了保证数据传递的可靠安全等等,ISO(国际标准委员会组织)将数据的传递从逻辑上划分为以下七层:... 查看详情

raknet是一个基于udp网络传输协议的c++网络库(还有一些其它库,比如nanomsg,fastsocket等等)

Raknet是一个基于UDP网络传输协议的C++网络库,允许程序员在他们自己的程序中实现高效的网络传输服务。通常情况下用于游戏,但也可以用于其它项目。Raknet有以下好处:高性能在同一台计算机上,Radnet可以实现在两个程序之间... 查看详情

网络协议_udp详谈(代码片段)

...点3.UDP首部格式4.UDP伪首部5.UDP面向数据报6.UDP的缓冲区7.基于UDP的应用层协议1.UDP简介Internet协议集支持一个无连接的传输协议,该协议称为用户数据报协议(UDP,UserDatagramProtocol)。UDP为应用程序提供了一种无需建... 查看详情

网络协议_udp详谈(代码片段)

...点3.UDP首部格式4.UDP伪首部5.UDP面向数据报6.UDP的缓冲区7.基于UDP的应用层协议8.UDP套接字编程1.UDP简介Internet协议集支持一个无连接的传输协议,该协议称为用户数据报协议(UDP,UserDatagramProtocol)。UDP为应用程序提... 查看详情

java网络编程基础---基于udp编程

    前面在介绍TCP/IP协议的时候我们已经提到,在TCP/IP协议的传输层除了TCP协议外还有一个UDP协议,相比UDP的应用不如TCP广泛,但是随着计算机网络的发展UDP协议正越来越显示出及其威力,尤其是在需要很强的实时... 查看详情

网络编程之基于udp协议套接字(代码片段)

...,并且不区分客户端先启动还是服务端前起,工作原理:基于udp协议传输的信息,协议会将数据自动加上自定义的报头,这样每一个数据都是一个数据报,而流失协议由于自身优化算法,产生粘包现象,udp不会产生粘包现象,并... 查看详情

网络编程——基于udp协议的套接字socketsocketserver模块的使用(代码片段)

基于udp协议的套接字、socketserver模块一、UDP协议(数据报协议)1、何为udp协议不可靠传输,”报头”部分一共只有8个字节,总长度不超过65,535字节,正好放进一个IP数据包。以太网头ip头         ... 查看详情

网络协议趣谈基于tcp和udp的套接字socket编程

在TCP和UDP协议中主要分客户端和服务端,在写程序的时候也同样这样分Socket这个名字很有意思,可以作插口或者插槽讲。虽然是软件程序,但可以想象为弄一根网线,一头插在客户端,一头插在服务端,然... 查看详情

java网络编程基于udp协议的通信

 使用UDP协议,写一个能在同一界面发送消息,并显示消息的聊天软件。代码实现如下:                packagecom.abel.socket;importjava.io.IOException;importjav 查看详情

网络--udp知识(代码片段)

...DP的功能比较弱,仅对IP层进行简单的接口包装,应用程序可基于UDP;而TCP可实现的功能,在应用程序层也可实现,那么即可绕开TCP,直接基于IP编程.TCP对比UDP协议TCPUDP是否可靠可靠不可靠[大概率丢包,乱序,重复]协议流式协议报文协议形... 查看详情

网络通信时选择基于tcp/ip协议还是udp/ip协议?

...失的信息,以提供传输性能。参考技术A网络通信时选择基于TCP/IP协议还是UDP/IP协议/两个都有,TCP是面向连接的可靠传输,三次握手建立可靠连接‘’就像打电话需要对方接听才能通讯UDP是面向无连接的不可靠传输就像发短信,... 查看详情

涨知识-vi基于tcp/udp的应用层协议

基于TCP/UDP的应用层协议:基于TCP:  Telnet(TeletypeovertheNetwork,网络电传),通过一个终端(terminal)登陆到网络  FTP(FileTransferProtocol文件传输协议)  SMTP(SimpleMailTransferProtocol简单邮件传输协议),用来发送电子邮件  POP3(PostOfficePr... 查看详情

复习之网络编程

...应用程序之间的通信端口port:唯一标识一台计算机某一个基于网络通信的应用程序标识的就是应用程序tcp面向流的协议,udp面向消息的协议是基于端口工作的,端口范围是0- 查看详情