Linux网络编程2

news2024/9/22 15:39:31

TCP编程

顺序图

socket() 函数

socket()函数用于创建一个新的套接字。它是进行网络编程的第一步,因为所有的网络通信都需要通过套接字来进行。

原型:

#include <sys/socket.h>  

int socket(int domain, int type, int protocol);

    domain:指定协议族,对于TCP/IP网络,它通常是AF_INET(IPv4)或AF_INET6(IPv6)。
    type:指定套接字类型,对于TCP连接,它通常是SOCK_STREAM。
    protocol:指定协议,通常对于AF_INET和SOCK_STREAM,协议为0,表示使用TCP协议。

返回值:成功时返回一个非负整数(套接字描述符),失败时返回-1,并设置errno。

bind() 函数

bind()函数用于将套接字与特定的IP地址和端口号绑定起来。这样,服务器就可以在这个特定的IP地址和端口上监听客户端的连接请求。

原型:

#include <sys/socket.h>  

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

    sockfd:通过socket()函数创建的套接字描述符。
    addr:指向sockaddr结构的指针,该结构包含IP地址和端口号。对于IPv4,通常使用sockaddr_in结构。

addr:采用struct sockaddr的结构体地址,通用结构体

struct sockaddr

{

        sa_family_t sa_family;

        char sa_data[4];

}

struct sockaddr_in

{         基于Internel通信结构体

        as_family_t sin_family;

        in_port_t sin_port;

        struct in_addr sin_addr;

        sin_zero , //填充字节,需清零

}

struct in_addr

{

        uint32_t s_addr;

}

    addrlen:addr参数指向的地址结构的长度。

返回值:成功时返回0,失败时返回-1并设置errno。

举个例子

其中注释

  • 使用socket()函数创建一个TCP套接字,并将其描述符存储在server_fd中。
  • 使用memset()函数将server_addr结构清,以确保所有未明确设置的字段都被初始化为0。
  • 设置server_addr结构的sin_familyAF_INET,表示使用IPv4地址。
  • sin_addr.s_addr设置为INADDR_ANY,这表示服务器将监听所有可用的网络接口
  • 使用htons()函数将端口号主机字节序转换为网络字节序,并将其存储在sin_port中。
  • 使用bind()函数将套接字server_fdserver_addr指定的地址和端口绑定
  • 注意:示例中没有实现监听连接和接受连接的代码,这些通常通过listen()accept()函数来完成。
  • 最后,使用close()函数关闭套接字以释放资源。

关于使用bind函数的结构体

bind()函数的调用中,你需要将sockaddr_in结构体的地址(即一个指向该结构体的指针)作为参数传递。你通过取地址操作符&来获取这个地址,并将其强制转换为struct sockaddr *类型(因为bind()函数的原型要求这个参数是struct sockaddr *类型,这是一个更通用的套接字地址结构体指针,sockaddr_in是它的一个特例)。

同时,你需要传递结构体的大小作为bind()函数的第三个参数。这是为了确保函数能够正确地解释传递给它的地址信息。你使用sizeof(server_addr)来获取这个大小。

listen() 函数

listen() 函数用于将套接字设置为监听状态,以接受连接请求。一旦套接字被设置为监听状态,它就可以接受来自客户端的连接请求。

函数原型:

#include <sys/socket.h> 

int listen(int sockfd, int backlog);

    sockfd:是之前通过socket()函数创建的套接字描述符。
    backlog:指定了内核应该为相应套接字排队的最大连接个数。当多个客户端同时尝试连接时,这个参数限制了可以处于半连接状态(即收到SYN包,但还未收到客户端确认的ACK包)的TCP连接的数量。注意,实际可排队的连接数可能会小于请求数,这取决于系统限制。(内核中的服务器的套接字fd会维护2个链表:1正在三次握手的客户端链表(数量=2*backlog+1)2已经完成三次握手分配好了的newfd)。如:listen(fd,5);//表示系统允许11(5*2+1)个客户同时进行三次握手

返回值:成功时返回0;失败时返回-1,并设置errno以指示错误。

accept() 函数

accept() 函数用于接受一个连接。当套接字处于监听状态时,accept() 函数会阻塞(除非套接字被设置为非阻塞模式),直到一个连接请求到达。一旦连接被接受,accept() 会创建一个新的套接字描述符,用于与连接的客户端进行通信,而原始的套接字描述符(即传递给listen()的那个)则继续用于监听新的连接请求。

函数原型:

#include <sys/socket.h> 

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

    sockfd:是之前通过socket()函数创建的并已经通过listen()设置为监听状态的套接字描述符。
    addr:是一个指向sockaddr结构的指针,该结构用于返回连接客户端的地址信息(可以用作查找客户机)。如果不需要客户端的地址信息,可以设置为NULL。
    addrlen:是一个指向socklen_t的指针,用于传入addr结构的大小,并在函数返回时更新为实际返回的地址信息的大小。

返回值:成功时返回一个新的套接字描述符,用于与连接的客户端通信;失败时返回-1,并设置errno以指示错误。

案例(四个函数一起使用):

关于上述的最后输出的printf("Connection accepted from %s:%d\n"inet_ntoa(client_addr.sin_addr), ntohs(client_addr.sin_port));

inet_ntoa()ntohs() 是两个用于网络编程的函数,它们分别用于将网络字节序(network byte order)转换为主机字节序(host byte order)的不同表示形式(socket函数介绍中有提到)。

inet_ntoa()用于将网络地址(通常是IPv4地址)从网络字节序的二进制形式转换为点分十进制字符串表示(例如,将 192.168.1.1 的二进制形式转换为文本字符串 "192.168.1.1")。

ntohs() 则是专门用于将无符号短整型(通常是端口号)从网络字节序转换为主机字节序。

通过上述学习的函数就可以成功写出一个简单的服务器端的代码,如下

如若要写客户端的代码,还需学习一个connect()函数

connect()函数

在网络编程中,connect 函数是一个非常重要的函数,它用于客户端程序来建立一个到服务器的连接。这个函数通常在套接字(socket)编程中使用,特别是在使用TCP协议时。connect 函数尝试将客户端的套接字与服务器上的套接字(或称为端口)建立连接。
函数原型:

在C语言(以及许多其他支持网络编程的语言)中,connect 函数的原型通常如下所示:

#include <sys/types.h>  
#include <sys/socket.h> 

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

参数说明

    sockfd:这是由socket函数返回的套接字描述符,代表客户端的套接字。
    addr:这是一个指向sockaddr结构(或其变体,如sockaddr_in用于IPv4)的指针,该结构包含了服务器的地址和端口信息。
    addrlen:这是addr参数所指向的结构的长度,以字节为单位。这允许connect函数知道它应该读取多少字节的地址信息。

返回值:

    成功时,connect函数返回0。
    出错时,返回-1,并设置全局变量errno以指示错误类型。

代码如下

实现功能如下

即一发一收,实现数据传递

这个代码可以被优化

下图修改了获取地址,通过这样可以自动搜索地址,无需宏定义地址

原代不能获取客户端的信息,修改之后通过accept()函数获取了客户端的地址与端口号信息

也能实现同样的功能

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

使用Go语言绘制饼图的教程

使用Go语言绘制饼图的教程 在本教程中&#xff0c;我们将学习如何使用Go语言及gg包绘制饼图&#xff0c;并将其保存为PNG格式的图片。饼图是一种常用的数据可视化图表&#xff0c;用于展示数据的比例关系和组成部分。 安装gg包 首先&#xff0c;确保你已经安装了gg包。如果还…

前端的学习-CSS(七)

一&#xff1a;定位(position) 1&#xff1a;为什么使用定位。 有一些固定的盒子&#xff0c;并且压在其他盒子上面&#xff0c;一些网页&#xff0c;会有固定的窗口&#xff0c;这些是标准流和浮动无法解决的&#xff0c;比如下面的例子。旁边的红色边框的效果是不会随着页面的…

汇昌联信数字做拼多多运营怎么入行?

拼多多作为中国领先的电商平台之一&#xff0c;近年来在数字运营领域展现出了强大的生命力和创新能力。汇昌联信数字作为一个潜在的新入行者&#xff0c;如何进入拼多多的运营领域&#xff0c;成为业界关注的焦点。本文旨在探讨汇昌联信数字如何通过有效的策略和方法&#xff0…

hal库回调函数机制

1. 第一行就是标准库函数的 在 nvic那个中断向量表里面的函数 以前写的都是 在中断向量表里面把这个中断处理函数重写 2. 第二行 第三行 的 hal库就是 通过中断向量表里面的这个函数 &#xff0c;再一次调用hal自己的中断回调函数&#xff0c;就是相当于多封装了两层 这个图更…

局部整体(二)利用python绘制维恩图

局部整体&#xff08;二&#xff09;利用python绘制维恩图 维恩图&#xff08; Venn Diagram&#xff09;简介 维恩图显示集与集之间所有可能存在的逻辑关系&#xff0c;每个集通常以一个圆圈表示&#xff0c;每个集都是一组具有共同之处的物件或数据。当多个圆圈&#xff08;…

【Material-UI】File Upload Button 组件详解

文章目录 一、基础实现1. component"label"2. 隐藏的输入元素 二、样式和交互增强1. 自定义按钮样式2. 交互提示 三、支持多文件上传四、无障碍性&#xff08;Accessibility&#xff09;1. 提供 aria-label 或 aria-labelledby2. 支持键盘导航 五、高级用法和集成1. …

leetcode-215. 数组中的第K个最大元素

题目描述 给定整数数组 nums 和整数 k&#xff0c;请返回数组中第 k 个最大的元素。 请注意&#xff0c;你需要找的是数组排序后的第 k 个最大的元素&#xff0c;而不是第 k 个不同的元素。 你必须设计并实现时间复杂度为 O(n) 的算法解决此问题。 示例 1: 输入: [3,2,1,5…

STM32-低功耗模式详解

一、概述 低功耗模式&#xff08;Low Power Mode&#xff09;是为了减少电子设备的能耗而设计的操作模式&#xff0c;广泛应用于依赖电池供电的设备中&#xff0c;旨在延长电池寿命或减少能源消耗。在用户需要设备长时间工作或在电量极为有限的情况下非常实用&#xff0c;虽然牺…

如何在IDEA上使用JDBC编程【保姆级教程】

目录 前言 什么是JDBC编程 本质 使用JDBC编程的优势 JDBC流程 如何在IEDA上使用JDBC JDBC编程 1.创建并初始化数据源 2.与数据库服务器建立连接 3.创建PreparedStatement对象编写sql语句 4.执行SQL语句并处理结果集 executeUpdate executeQuery 5.释放资源 前言 在…

yandex 不定长旋转验证码PPOCR识别案例

注意,本文只提供学习的思路,严禁违反法律以及破坏信息系统等行为,本文只提供思路 如有侵犯,请联系作者下架 某yandex 不定长旋转验证码如下: 可以看到,此种验证码非常变态,旋转角度不固定,干扰背景不固定,字符长度不固定,弯曲形变都是不固定的,在人眼都很难分辨验证…

『 C++ 』异常

文章目录 异常概念及使用自定义类型的异常C 标准库的异常体系异常的重新抛出异常安全异常规范异常的优缺点 异常概念及使用 C语言常见的错误处理机制如下: 返回值约定 通过定义一些列的返回值以及其对应的错误信息表述,通过不同的返回值来查看当前函数是否与调用成功; 通常情…

锂电池生产工艺数字化的业务架构.pptx

搜索《方案驿站》公众号进行下载。

【系统架构设计】数据库系统(五)

数据库系统&#xff08;五&#xff09; 数据库模式与范式数据库设计备份与恢复分布式数据库系统数据仓库数据挖掘NoSQL大数据 数据库模式与范式 数据库设计 备份与恢复 分布式数据库系统 数据仓库 数据挖掘 对数据挖掘技术进行支持的三种基础技术已经发展成熟&#xff0c…

【设计模式】六大原则-上

首先什么是设计模式&#xff1f; 相信刚上大学的你和我一样&#xff0c;在学习这门课的时候根本不了解这些设计原则和模式有什么用处&#xff0c;反而不如隔壁的C更有意思&#xff0c;至少还能弹出一个小黑框&#xff0c;给我个hello world。 如何你和我一样也是这么想&#xf…

2-56 基于matlab的图像融合增强技术

基于matlab的图像融合增强技术。通过原始图像——傅里叶变换——频率域滤波处理——傅里叶变换——增强后的图像。傅立叶变换以及傅立叶反变换.过程就是将空间的信息分解为在频率上的表示,通过傅立叶正反变换的处理,才使得频率域上的处理可以用于图像的增强。程序已调通&#x…

联想QuickFix工具中心,一款综合性电脑维护和管理工具

联想QuickFix工具中心是联想公司推出的一款综合性电脑维护和管理工具&#xff0c;它集成了众多实用的电脑维护工具&#xff0c;如系统优化、硬盘清理、网络优化、硬件诊断等&#xff0c;旨在为用户提供一个便捷的平台来解决电脑日常使用中遇到的各种问题。该工具中心适用于Wind…

AttributeError: ‘ChatGLMTokenizer‘ object has no attribute ‘sp_tokenizer‘. 已解决

&#x1f4d1;打牌 &#xff1a; da pai ge的个人主页 &#x1f324;️个人专栏 &#xff1a; da pai ge的博客专栏 ☁️宝剑锋从磨砺出&#xff0c;梅花香自苦寒来 ☁️运维工程师的职责&#xff1a;监…

【Linux---07】Shell脚本

文章目录 1. 前置说明1.1 创建shell脚本1.2 执行shell脚本1.3 调试shell脚本1.4 字符冲突 2. 变量2.1 创建&使用变量2.2 位置变量2.3 引号规则2.4 数值变量运算 3. 数组3.1 创建数组3.2 使用数组 4. 运算符4.1 比较运算符4.1.1 数字比较4.1.2 字符串比较 4.2 逻辑运算符4.3…

国内首个可调用API的视频模型,CogVideoX有多能打?

近期&#xff0c;智谱AI在其Maas开放平台(bigmodel.cn)发布了视频生成大模型CogVideoX&#xff0c;它提供了国内首个通过API来使用的文生视频和图生视频服务&#xff01; 话不多说&#xff0c;我们直接来看一下通过CogVideoX生成的一部短片。 技术原理 CogVideoX融合了文本、…

CSP-J复赛-模拟题4

1.区间覆盖问题&#xff1a; 题目描述 给定一个长度为n的序列1,2,...,a1​,a2​,...,an​。你可以对该序列执行区间覆盖操作&#xff0c;即将区间[l,r]中的数字,1,...,al​,al1​,...,ar​全部修改成同一个数字。 现在有T次操作&#xff0c;每次操作由l,r,p,k四个值组成&am…