Linux系统编程(14)UDP全双工通信和TCP半双工通信

一、UDP全双工通信

UDP通信基础:
recvfrom函数

  recvfrom 是一个用于接收数据的函数,,但 recvfrom 不仅接收数据,还可以获取发送数据的地址信息。

ssize_t recvfrom(int sockfd, void *buf, size_t len, int flags, struct sockaddr *src_addr, socklen_t *addrlen);
  • sockfd: 指定用于接收数据的套接字描述符。它通常是通过 socket() 函数创建的。

  • buf: 指向接收数据的缓冲区的指针。

  • len: 指定缓冲区的大小,即要接收的数据的最大字节数。

  • flags: 接收数据时的标志位,默认为0

  • src_addr: 指向存储发送方地址信息的 sockaddr 结构体的指针。如果不关心发送方的地址信息,可以传入 NULL

  • addrlen: 指向 src_addr 结构体长度的指针。在函数返回时,它将包含实际的地址长度。

  • 成功时,recvfrom 返回接收到的字节数。
  • 出错时,返回 -1
bind函数

    bind 函数在网络编程中用于将一个套接字与一个特定的地址(IP地址和端口号)绑定。它主要用于服务器端,使得服务器能够监听来自特定地址的连接请求。

int bind(int sockfd, const struct sockaddr *addr, socklen_t addrlen);
  • sockfd: 套接字文件描述符。这个套接字是通过 socket() 函数创建的,表示一个未绑定的套接字。

  • addr: 指向 sockaddr 结构体的指针,包含要绑定到的地址信息。通常使用 sockaddr_in 结构体来表示IPv4地址(对于IPv6使用 sockaddr_in6),然后将其强制转换为 sockaddr* 类型。

  • addrlen: 结构体 sockaddr 的大小,通常使用 sizeof(struct sockaddr_in)sizeof(struct sockaddr_in6)

  • 成功时,返回 0
  • 出错时,返回 -1

struct sockaddr结构体:

   struct sockaddr      通用地址结构 --- ip + 端口 {u_short sa_family;  地址族char sa_data[14];   地址信息};

      转换成网络地址结构如下:
    

 struct sockaddr_in    ///网络地址结构{u_short           sin_family; //地址族u_short           sin_port;   //地址端口struct in_addr  sin_addr;   //地址IP  //"192.168.1.123"char               sin_zero[8]; //占位};
其中sin_addr结构体:struct in_addr{in_addr_t s_addr;};
基于UDP实现的全双工通信
client.c
//使用多进程实现客户端的的收和发
#include<stdio.h>
#include <sys/types.h>          /* See NOTES */
#include <sys/socket.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netinet/ip.h> /* superset of previous */
#include <string.h>
#include <arpa/inet.h>
#include <signal.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <unistd.h>
int main(int argc , char *argv[])
{int fd = socket(AF_INET,SOCK_DGRAM,0);if(fd < 0){perror("socket error");return 0;}char buf[1024];struct sockaddr_in seraddr;seraddr.sin_family = AF_INET;seraddr.sin_port = htons(50000);seraddr.sin_addr.s_addr = inet_addr("192.168.85.128");struct sockaddr_in srcaddr;socklen_t srcaddrlen = sizeof(srcaddr);pid_t pid = fork();if(pid < 0){perror("fork fail");return 0;}if(pid > 0){while(1){printf("client >");bzero(buf,sizeof(buf));fgets(buf,sizeof(buf),stdin); sendto(fd,buf,strlen(buf),0,(const struct sockaddr *)&seraddr,sizeof(seraddr));if(strncmp(buf,"quit",4) == 0){kill(pid,9);wait(NULL);return 0;}}}if(pid == 0){while(1){recvfrom(fd,buf,sizeof(buf),0,NULL,NULL);printf(" %s\n",buf);}}return 0;
}
server.c
//使用多进程实现服务端的收和发
#include<stdio.h>
#include <sys/types.h>          /* See NOTES */
#include <sys/socket.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netinet/ip.h> /* superset of previous */
#include <string.h>
#include <arpa/inet.h>
#include <signal.h>
#include<sys/types.h>
#include <sys/wait.h>
#include <unistd.h>
void handler(int signo)
{wait(NULL);kill(getpid(),9);
}
int main(int argc , char *argv[])
{int fd = socket(AF_INET,SOCK_DGRAM,0);if(fd < 0){perror("socket error");return 0;}char buf[1024];struct sockaddr_in seraddr;seraddr.sin_family = AF_INET;seraddr.sin_port = htons(50000);seraddr.sin_addr.s_addr = inet_addr("192.168.85.128");struct sockaddr_in srcaddr;socklen_t srcaddrlen = sizeof(srcaddr);bind(fd,(const struct sockaddr *)&seraddr,sizeof(seraddr));recvfrom(fd,buf,sizeof(buf),0,(struct sockaddr *) & srcaddr,&srcaddrlen);if(strncmp(buf,"quit",4) == 0){return 0;}printf("receive :%s",buf);printf("receive from : %s\n",inet_ntoa(srcaddr.sin_addr));printf("port : %d\n",ntohs(srcaddr.sin_port));char returnbuf[2048];pid_t pid = fork();if(pid < 0){perror("fork fail");return 0;}if(pid > 0){ while(1){   //signal(SIGCHLD,handler);//bzero(buf,sizeof(buf));printf("server >");fgets(buf,sizeof(buf),stdin);sprintf(returnbuf,"%s%s","\nfrom server:",buf);sendto(fd,returnbuf,strlen(returnbuf),0,(const struct sockaddr *)&srcaddr,sizeof(srcaddr));}}if(pid == 0){while(1){recvfrom(fd,buf,sizeof(buf),0,(struct sockaddr *) & srcaddr,&srcaddrlen);if(strncmp(buf,"quit",4) == 0){break;}printf("receive :%s",buf);printf("receive from : %s\n",inet_ntoa(srcaddr.sin_addr));printf("port : %d\n",ntohs(srcaddr.sin_port));}return 0;}
}

二、TCP通信

由于TCP面向连接和可靠性高的特性,因此,在使用TCP协议通信时,需要在客户端和服务端之间先建立连接才能进行数据通信。

TCP通信流程

listen函数

listen 函数用于将一个套接字设置为监听模式,等待客户端的连接请求。

int listen(int sockfd, int backlog);
  • sockfd: 套接字文件描述符。这个套接字必须已经用 socket() 函数创建,并且使用 bind() 函数绑定到了一个特定的地址和端口。

  • backlog: 指定内核为该套接字排队的最大连接数。这表示在 accept() 函数处理之前,内核可以排队等待的最大连接数。如果有更多的连接请求到达,新的连接可能会被拒绝或未处理,直到队列中有空闲位置。

  • 成功时,返回 0
  • 出错时,返回 -1

connect函数  

 int connect(int sockfd, const struct sockaddr *addr,socklen_t addrlen);

 功能:该函数固定有客户端使用,表示从当前主机向目标
            主机发起链接请求。
   参数:sockfd 本地socket创建的套接子id
                    addr 远程目标主机的地址信息。
                 addrlen: 参数2的长度。
   返回值:成功 0
              失败 -1;

accept函数
int accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen);

accept 函数用于服务器端网络编程,在套接字处于监听模式时,accept 函数会从监听队列中提取第一个连接请求,并为该连接创建一个新的套接字(专门用来连接)

  • sockfd: 监听套接字的文件描述符。这个套接字是通过 socket() 创建的,并且已经通过 bind() 绑定到了一个地址和端口,通过 listen() 函数进入了监听状态。

  • addr: 指向 sockaddr 结构体的指针,accept 函数将填充客户端的地址信息到该结构体中。如果你不关心客户端的地址,可以将其设置为 NULL

  • addrlen: 一个值-结果参数,它指向一个保存了 addr 结构大小的变量。在函数返回时,这个变量会包含客户端地址结构的实际大小。如果 addrNULL,则 addrlen 也应为 NULL

  • 成功时,返回一个新的文件描述符,这个描述符代表新建立的连接。服务器通过这个新套接字与客户端进行通信。
  • 出错时,返回 -1,并设置 errno 以指示错误类型。

这几个函数之间的关系

listen函数将创建的socket套接字设置为监听模式后,创建一个序列用来存储请求连接的设备,accept函数每次将第一个在队列中的请求进行处理后产生一个用来通信的和客户端建立连接的新的套接字 ,用来负责后续的通信

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/406516.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

融资管理系统项目

系列文章目录 第一章 基础知识、数据类型学习 第二章 万年历项目 第三章 代码逻辑训练习题 第四章 方法、数组学习 第五章 图书管理系统项目 第六章 面向对象编程&#xff1a;封装、继承、多态学习 第七章 封装继承多态习题 第八章 常用类、包装类、异常处理机制学习 第九章 集…

指针的学习和理解

初级 1、指针的概念 在64位操作系统中&#xff0c;不管什么类型的指针都占8个字节 int a1; int* p&a;//p就是一个整型的指针&#xff0c;保存了a的地址2、指针和变量 int* p&a;* p100; // 等价于a100p //p&a*有两种定义&#xff1a; 定义的时候&#xff08;前…

IP报文详解

IP的作用 上一篇文章提到TCP的可靠传输机制&#xff0c;那么TCP有把数据从主机A到主机B的能力吗&#xff1f;答案是没有。而IP有这个能力&#xff0c;IP能够将数据从主机A跨网络传输到主机B的能力。那么一定能传输成功吗&#xff1f;答案肯定是否定的&#xff0c;会因为各种原…

使用 Python构建 Windows 进程管理器应用程序

在这篇博客中&#xff0c;我们将探讨如何使用 wxPython 构建一个简单的 Windows 进程管理器应用程序。这个应用程序允许用户列出当前系统上的所有进程&#xff0c;选择和终止进程&#xff0c;并将特定进程保存到文件中以供将来加载。 C:\pythoncode\new\manageprocess.py 全部…

普元EOS-数据实体运行时动态增加property

1 前言 在Java开发读取数据的时候&#xff0c;一般都采用ORM方式将数据表的字段映射到实体对象中。 数据表中有一个字段&#xff0c;实体对象就有一个字段。 但很多时候&#xff0c;我们在读取的数据和显示的数据不同&#xff0c;比如&#xff0c;读取的是部门id&#xff0c…

探索数据结构:图(一)之邻接矩阵与邻接表

✨✨ 欢迎大家来到贝蒂大讲堂✨✨ &#x1f388;&#x1f388;养成好习惯&#xff0c;先赞后看哦~&#x1f388;&#x1f388; 所属专栏&#xff1a;数据结构与算法 贝蒂的主页&#xff1a;Betty’s blog 1. 图的定义 **图&#xff08;Graph&#xff09;**是数学和计算机科学中…

这周末,除非外面下钞票,否则谁也拦不住我玩《黑神话悟空》(附:两款可以玩转悟空的显卡推荐)

主播说联播 | 从“十分之三”到“悟空”,国潮有何出圈密码? 《黑神话:悟空》里的中国古建取景地,在这里! 这周末,除非外面下钞票,否则谁也拦不住我玩《黑神话悟空》(附:两款可以玩转悟空的显卡推荐) 原创 IPBrain平台君 集成电路大数据平台 2024年08月22日 17:28 …

gif图片怎么压缩大小?深度测评7款动图压缩工具(内含教程)

gif图片在社交媒体和网络上非常流行&#xff0c;深受大家喜爱&#xff0c;因为它可以呈现生动的动画效果。gif动图之所以受到欢迎&#xff0c;主要因为其出色的压缩算法&#xff0c;能有效存储多个帧&#xff0c;从而实现流畅的动画。 然而&#xff0c;大多数社交媒体平台对gi…

[数据集][目标检测]集装箱缺陷检测数据集VOC+YOLO格式4127张3类别

数据集格式&#xff1a;Pascal VOC格式YOLO格式(不包含分割路径的txt文件&#xff0c;仅仅包含jpg图片以及对应的VOC格式xml文件和yolo格式txt文件) 图片数量(jpg文件个数)&#xff1a;4127 标注数量(xml文件个数)&#xff1a;4127 标注数量(txt文件个数)&#xff1a;4127 标注…

全新分支版本!微软推出Windows 11 Canary Build 27686版

已经很久没有看到 Windows 11 全新的分支版本了&#xff0c;今天微软发布 Windows 11 Canary 新版本&#xff0c;此次版本号已经转移到 Build 27xxx&#xff0c;首发版本为 Build 27686 版。 此次更新带来了多项改进&#xff0c;包括 Windows Sandbox 沙盒功能切换到 Microsof…

关于智能编码助手【通义灵码】,开发者们这么说...

自通义灵码发布以来&#xff0c;不停地有开发者朋友为我们送上通义灵码的测评反馈。 关于通义灵码&#xff0c;开发者这样说 墨问西东 CEO 池建强&墨问研发团队 “通义灵码有一个强大的功能就是企业知识库检索增强&#xff0c;我们只需要上传团队的代码规范&#xff0c;…

[数据集][目标检测]快递包裹检测数据集VOC+YOLO格式5382张1类别

数据集格式&#xff1a;Pascal VOC格式YOLO格式(不包含分割路径的txt文件&#xff0c;仅仅包含jpg图片以及对应的VOC格式xml文件和yolo格式txt文件) 图片数量(jpg文件个数)&#xff1a;5382 标注数量(xml文件个数)&#xff1a;5382 标注数量(txt文件个数)&#xff1a;5382 标注…

【C语言小项目】五子棋游戏

目录 前言 一、游戏规则 1.功能分析 2.玩法分析 3.胜负判定条件 二、游戏实现思路 三、代码实现与函数封装 1.项目文件创建 2.头文件说明 3.函数封装 1&#xff09;菜单实现 2&#xff09;进度条实现 3&#xff09;main函数实现 4&#xff09;Game函数 5&#xff0…

TIM输出比较之PWM驱动LED呼吸灯应用案例

文章目录 前言一、应用案例演示二、电路接线图三、应用案例代码四、应用案例分析4.1 基本思路4.2 相关库函数介绍4.3 初始化PWM模块4.3.1 RCC开启时钟4.3.2 配置时基单元4.3.3 配置输出比较单元4.3.4 配置GPIO4.3.5 运行控制 4.4 PWM输出模块4.5 主程序 前言 提示&#xff1a;…

[数据集][目标检测]竹子甘蔗发芽缺陷检测数据集VOC+YOLO格式2953张3类别

数据集格式&#xff1a;Pascal VOC格式YOLO格式(不包含分割路径的txt文件&#xff0c;仅仅包含jpg图片以及对应的VOC格式xml文件和yolo格式txt文件) 图片数量(jpg文件个数)&#xff1a;2953 标注数量(xml文件个数)&#xff1a;2953 标注数量(txt文件个数)&#xff1a;2953 标注…

电脑录屏高清视频制作:如何选择适合的分辨率和参数

在当今数字化时代&#xff0c;无论是教学、演示还是游戏直播&#xff0c;电脑录屏已经成为了一个不可或缺的工具。然而画质往往是录屏质量的关键因素&#xff0c;许多用户在追求高清录屏体验时&#xff0c;常常面临选择1080p还是4K分辨率的困惑。本文将深入探讨如何优化电脑录屏…

SpringBoot自动配置

一、Condition条件判断功能 Condition 是在Spring 4.0 增加的条件判断功能&#xff0c;其主要作用是判断条件是否满足&#xff0c;从而决定是否初始化并向容器注入Bean对象。通过Conditional注解及其一系列的其他相关注解实现。 在Spring Boot中&#xff0c;条件匹配&#xf…

性能优化理论篇 | swap area是个什么东西

我们知道每台计算机的内存&#xff08;RAM&#xff09;都是有限的&#xff0c;而我们的应用程序需要加载到内存才能被运行&#xff0c;如果一台机器运行多个应用程序时&#xff0c;内存可能会耗尽。Linux 系统中的“交换空间&#xff08;也称为交换分区&#xff09;”可以帮助缓…

使用AWS Lambda轻松开启Amazon Rekognition之旅

这是本系列文章的第一篇&#xff0c;旨在通过动手实践&#xff0c;帮助大家学习亚马逊云科技的生成式AI相关技能。通过这些文章&#xff0c;大家将掌握如何利用亚马逊云科技的各类服务来应用AI技术。 那么让我们开始今天的内容吧&#xff01; 介绍 什么是Amazon Rekognition&…

微软的免费“后悔药“-Windows File Recovery (WinFR)

微软的免费"后悔药"-Windows File Recovery (WinFR) 当你不小心误删除了文件或因各种意外情况导致数据丢失&#xff0c;可以使用 EasyRecovery、Disk Drill、DiskGenius、Recuva 等“上古”软件&#xff0c;也可以交由专业机构进行恢复。微软&#xff08;Microsoft&…