首页 > 系统相关 >Linux网络编程(socket的udp通信)

Linux网络编程(socket的udp通信)

时间:2023-07-17 16:11:18浏览次数:41  
标签:udp addr int Linux sockfd include buf socket

UDP是无连接的,即发送数据之前不需要建立连接,它尽最大努力交付,即不保证可靠交付,在一些要求实时性的通信中多有用到如游戏,视频等,UDP是面向报文的,有别于tcp的一对一通信,udp支持一对一、一对多、多对一和多对多的交互通信等。   一、udp通信用到的相关函数解析 int socket(int domain, int type, int protocol); 功能:创建socket对象 type:SOCK_DGRAM 数据报协议 UDP   int bind(int sockfd, const struct sockaddr *addr,socklen_t addrlen); 功能:绑定socket和通信地址 sockfd:socket描述符 addr:地址结构体指针,实际传递的是 sockaddr_un或者sockaddr_in 结构体指针,需要把它们统一转换为sockaddr*类型。具体sockaddr_in结构体在socket的本地通信博文中有提到,这里不再赘述。   UDP专属的数据发送接收函数: ssize_t sendto(int sockfd, const void *buf, size_t len, int flags,const struct sockaddr *dest_addr, socklen_t addrlen); 功能:UDP协议发送数据 sockfd:socket描述符 buf:待发送数据内存首地址 len:待发送数据的字节数 flags:是否阻塞 一般写0阻塞即可 dest_addr:通信目标的地址 addrlen:地址结构体的字节数 返回值:成功发送的字节数,0表示通信关闭,-1表示出现错误   ssize_t recvfrom(int sockfd, void *buf, size_t len, int flags,struct sockaddr *src_addr, socklen_t *addrlen); 功能:UDP协议接收数据 sockfd:socket描述符 buf:存储接收数据的缓冲区内存首地址 len:缓冲区的字节数 flags:是否阻塞 一般写0阻塞即可 src_addr:用于存储发送者的地址 addrlen:既是输入,也是输出,既告诉函数当前src_addr结构体的字节数,同时也能实际接收到发送者的地址结构体字节数。 返回值:成功接收到的字节数,0表示通信关闭,-1表示出现错误。   二、udp通信的编程模型 基于UDP通信协议的网络通信编程模型:      接收端                 发送端 创建socket             创建socket 准备通信地址            准备通信地址 绑定                   ... 接收请求                发送请求 响应请求                接收响应 关闭socket              关闭socket   三、dup通信编程示例 服务器端 #include <stdio.h> #include <stdlib.h> #include <string.h> #include <unistd.h> #include <sys/socket.h> #include <netinet/in.h> #include <arpa/inet.h> #include <sys/types.h>   typedef struct sockaddr* SP;   int main(int argc,const char* argv[]) { //创建socket int sockfd = socket(AF_INET,SOCK_DGRAM,0); if(0 > sockfd) { perror("socket"); return EXIT_FAILURE; }   //准备本机通信地址 struct sockaddr_in srv_addr = {},cli_addr = {}; srv_addr.sin_family = AF_INET; srv_addr.sin_port = htons(7788);     //这里的“xxx.xx.xx.xx”写本机的ip地址,可以用ifconfig命令查看,windows可以用ipconfig查看 srv_addr.sin_addr.s_addr = inet_addr("xxx.xx.xx.xx"); socklen_t addrlen = sizeof(srv_addr);   //绑定 if(bind(sockfd,(SP)&srv_addr,addrlen)) { perror("bind"); return EXIT_FAILURE; }   char buf[4096] = {}; size_t buf_size = sizeof(buf);   for(;;) { //接收数据和对方的地址 int ret = recvfrom(sockfd,buf,buf_size,0,(SP)&cli_addr,&addrlen); if(0 >= ret) { printf("网络异常,通信结束!"); close(sockfd); return EXIT_FAILURE; } printf("from %s recv:[%s] bits:%d\n", inet_ntoa(cli_addr.sin_addr),buf,ret);   //返回响应 strcat(buf,"from udpS"); ret = sendto(sockfd,buf,strlen(buf)+1,0,(SP)&cli_addr,addrlen); if(0 >= ret) { printf("对方网络异常!\n"); } } }   客户端 #include <stdio.h> #include <stdlib.h> #include <string.h> #include <unistd.h> #include <sys/socket.h> #include <netinet/in.h> #include <arpa/inet.h> #include <sys/types.h>   typedef struct sockaddr* SP;   int main(int argc,const char* argv[]) { //创建socket int sockfd = socket(AF_INET,SOCK_DGRAM,0); if(0 > sockfd) { perror("socket"); return EXIT_FAILURE; }   //准备服务器通信地址 struct sockaddr_in srv_addr = {}; srv_addr.sin_family = AF_INET; srv_addr.sin_port = htons(7788); srv_addr.sin_addr.s_addr = inet_addr("xx.xx.xxx.xxx");//这里写需要通信的ip地址 socklen_t addrlen = sizeof(srv_addr);   char buf[4096] = {}; size_t buf_size = sizeof(buf);   for(;;) { printf(">>>"); scanf("%s",buf); if(0 == strcmp(buf,"quit")) { printf("结束通信!\n"); close(sockfd); return EXIT_SUCCESS; } int ret = sendto(sockfd,buf,strlen(buf)+1,0,(SP)&srv_addr,addrlen); if(0 >= ret) { printf("网络异常!\n"); close(sockfd); return EXIT_FAILURE; } //接收数据和对方的地址 ret = recvfrom(sockfd,buf,buf_size,0,(SP)&srv_addr,&addrlen); if(0 >= ret) { printf("网络异常,通信结束!"); close(sockfd); return EXIT_FAILURE; } printf("from %s recv:[%s] bits:%d\n", inet_ntoa(srv_addr.sin_addr),buf,ret);   } }  

标签:udp,addr,int,Linux,sockfd,include,buf,socket
From: https://www.cnblogs.com/kn-zheng/p/17560402.html

相关文章

  • Linux磁盘专题
    物理磁盘名次和其作用盘片:disk盘片上下都有磁头。磁盘面:盘片有上下两面,每一面叫磁盘面磁头:heads每个磁头负责一个磁盘面,负责读取数据、将数据写入磁道。磁头都是固定在机械臂上(机械臂就是磁头臂组支架)磁道:track每个磁盘面上围绕圆心划分出多个同心圆环,每个圆圈叫做磁......
  • Linux磁盘专题-常用分区命令
    划分分区fdisk专门用于划分MBR类型的分区。(mbr分区类型在linx中也叫msdos)注意:fdisk在centos7上已经可以用来划分gpt类型的分区。详细不说了,N年之前学习过gdisk专用与划分gpt类型分区。大致操作和fdisk一样,不记录了,N年前学过。。partedparted之前懒得学,现在看了下也是......
  • Linux磁盘专题-linux文件系统详解
    这可是我几年前的杰作笔记呀.....当初手写计算都会,现在忘光光....物理硬盘Block的概念和作用硬盘底层一次IO就是读、写一次扇区,一个扇区默认是512Byte。读写大量文件如果以扇区为单位会很慢、性能不好,所以出现了逻辑块的概念(logicblock),也就是硬盘Block。逻辑块Block是......
  • Linux下服务service使用记录
    在/etc/systemd/system/路径下添加MyService.service文件并写入一下内容()[Unit]Description=MyService[Service]Type=simple#工作路径WorkingDirectory=/home/software/net5.0/publish#执行的服务的dll文件ExecStart=/usr/bin/dotnet/home/software/net5.0/publish/M......
  • linux搭建code-server及使用中遇到的问题
    系统环境CentOS8.5docker搭建linux不太熟,但是用docker搭建是真的简单,有现成的镜像的话一句命令就可以搞定。dockerrun-itd--namemy-code-server\-p5580:8080\-v/data/mycode:/home/coder\-ePASSWORD=12345678\codercom/code-server:latest--authpassword......
  • linuxIP地址和主机名,再虚拟机中配置linux固定IP
    1.IP地址IPV4版本地址格式:a.b.c.d,其中abcd是0-255的数字可以通过ifconfig查看本机的IP地址2.特殊IP地址127.0.0.1,表示本机0.0.0.0,可以指代本机,也可以在端口绑定中用来确定绑定关系,还可以在IP地址限制中表示所有的IP允许所有IP访问3.主机名每一台电脑除......
  • Linux下建立NFS共享目录
    https://blog.csdn.net/anluo233/article/details/125921403https://blog.csdn.net/zhangxucumt/article/details/125935901......
  • java在指定目录执行linux命令
    在指定目录执行Linux命令的Java实现概述在Java程序中通过执行Linux命令可以实现一些系统级别的操作,比如启动、停止进程,创建、删除目录等。本文将向刚入行的小白开发者介绍如何在Java中执行Linux命令,并指导他完成该过程。步骤步骤动作代码1创建ProcessBuilder对象Pr......
  • Java 实现 WebSocket 集群转发:使用 Redis 发布订阅
    场景浏览器客户端client1连接到了服务端A的websocket节点。浏览器客户端通过弹性负载均衡,把请求分配到了服务端B,服务端B上没有client1的连接。需求服务端B把消息转发到服务端A上,找到客户端client1的连接,发送出去。画示意图......
  • 跟运维学 Linux - 01
    跟运维学Linux-01运维的诞生运维工程师有很多叫法:系统运维、Linux工程师、系统管理员...网管可以说是运维工程师最早的雏形。在个人电脑未普及时,大家去网吧玩游戏。玩家:“网关,我的电脑上不了网了”网管负责维修电脑、维修系统、维护网络设备...互联网的发展现在大家在......