Linux 操作系统TCP、UDP

news2024/11/27 11:48:21

1、TCP服务器编写流程

头文件:

#include <sys/socket.h>

1.1 创建套接字

函数原型:

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

参数:

        domain: 网域
               AF_INET : IPv4
               AF_INET6 : IPv6
               AF_UNIX : 本地通讯

type:选择传输协议  tcp/udp

                SOCK_STREAM ; tcp
                SOCK_DGRAM : udp

protocol: 基本废弃, 一般赋 0
返回值: 成功返回描述网络套接字 sockfd, 失败返回-1
举例: 创建描述网络的套接字:

int sfd = socket(AF_INET,SOCK_STREAM,0);

1.2 绑定

头文件:

#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>

作用:绑定一个端口和IP地址,使套接口与指定的端口号和IP地址相关联

函数原型:

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

参数:

        sockfd 为前面 socket 的返回值, 描述网络的套接字
        my_addr:封装 ip 地址和端口号

struct sockaddr //一般很少用
{
    unsigned short int sa_family; // AF_INET。
    char sa_data[14]; //IP 和端口
};
struct sockaddr_in //常用的结构体
{
    unsigned short int sin_family; //AF_INE
    uint16_t sin_port; //使用的 port 编号
    struct in_addr sin_addr; // IP 地址
    unsigned char sin_zero[8]; //未使用
};

端口:10000-65535之间随意选

转化:

uint32_t htonl(uint32_t hostlong);//本函数将一个 32 位数从主机字节顺序转换成无符号长整型网络字节顺序
uint16_t htons(uint16_t hostshort);//将一个无符号短整型的主机数值转换为网络字节顺序
uint32_t ntohl(uint32_t netlong);//将一个无符号长整形数从网络字节顺序转换为主机字节顺序。
uint16_t ntohs(uint16_t netshort);//将一个 16 位数由网络字节顺序转换为主机字节顺序。

IP的填写方式:

struct in_addr
{
    uint32_t s_addr; //=inet_addr("192.168.1.22");
};

返回值:成功则返回0,失败返回-1

举例:

#define PORT 33333
#define IP "192.168.110.123"
struct sockaddr_in ser_addr;
ser_addr.sin_family = AF_INET;
ser_addr.sin_port = htons(PORT);
ser_addr.sin_addr.s_addr = inet_addr(IP);
inet_aton(“192.168.1.22”,&ser_addr.sin_addr);
bind(sfd,(struct sockaddr)&ser_addr,sizeof(ser_addr));

1.3 监听

作用:设置允许的最大连接数(瞬间处理的阀值),listen函数。

使用服务器的这个端口和IP处于监听状态,等待网络中某一客户机的连接请求。如果客户端哟连接请求,端口就会接受这个链接。

函数原型:

int listen(int sockfd, int backlog);

参数:

        sockfd 为前面 socket 的返回值, sfd
        backlog 指定同时能处理的最大连接要求, 通常为 10 或者 5。 最大值可设至 128( 不是最多可以连接 128个客户端, 是一个瞬时处理的阈值)
返回值: 成功则返回 0, 失败返回-1

1.4 等待客户端连接

函数原型:

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

参数:

        sockfd 为前面 socket 的返回值, 即 sfd
        addr: 提供空间, 用于接受客户端的 ip 地址和端口号
        addrlen: 第二个参数大小

返回值:

        返回新的套接字描述符, 专门用于与建立的客户端通信
        失败-1;

举例:

struct sockaddr_in cli_addr = {0};
socklen_t len = sizeof(cli_addr);
int cfd = accept(sfd,(struct sockaddr *)&cli_addr,&len);

1.5 读写函数

可以使用read和write函数进行。

写函数

函数原型;

ssize_t send(int s, const void *buf, size_t len, int flags);

参数:

        s: 通信套接字
        buf: 要发送的数据缓冲区
        len: 数据长度
        flags: 一般赋 0 .阻塞

返回值:成功返回真正发送的数据长度,失败-1.

读函数

函数原型:

ssize_t recv(int s, void *buf, size_t len, int flags);

参数:

        s: 通信的套接字
        buf:存放接收数据的缓冲区
        len: 数据长度
        flags: 一般赋 0 .阻塞

返回值:成功返回真正接收的数据长度,失败-1.

2 TCP客户端编写流程

2.1 创建套接字

头文件:

#include <sys/socket.h>

函数原型:

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

参数:

        domain: 网域
                AF_INET : IPv4
                AF_INET6 : IPv6
        type: 选择传输协议 tcp /udp
                SOCK_STREAM ; tcp
                SOCK_DGRAM : udp
        protocol: 基本废弃, 一般赋 0

返回值:成功返回套接字fd,失败返回-1

2.2 连接

函数原型:

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

参数:

    sockfd 为前面 socket 的返回值, 即 fd
    serv_addr 为结构体指针变量, 存储着远程服务器的 IP 与端口号信息。
    addrlen 表示结构体变量的长度

返回值:成功则返回0,失败返回-1

举例:

    int fd = socket(AF_INET,SOCK_STREAM,0);
    #define PORT 33333
    #define IP "192.168.110.123"
    struct sockaddr_in ser_addr;
    ser_addr.sin_family = AF_INET;
    ser_addr.sin_port = htons(PORT);
    ser_addr.sin_addr.s_addr = inet_addr(IP);
    connect(fd,(struct sockaddr *)&ser_addr,sizeof(ser_addr));

TCP 问题: 当服务器结束之后, 再次运行会出现 bind 错误(地址被占用)
解决办法:

      int sfd = socket(AF_INET,SOCK_STREAM,0);


创建套接字之后, 用:

int val = 1;
setsockopt(sfd,SOL_SOCKET,SO_REUSEADDR,&val,sizeof(val));
setsockopt(sfd,SOL_SOCKET,SO_REUSEPORT,&val,sizeof(val));

3.UDP

特点:非面向连接,不可靠传输,传输速率高

分别有:

单播  --  一对一                广播  --  一对多          组播  --  多对多

3.1 单播

        UDP不像TCP。无需在连接状态下交换数据,因此基于UDP的接收方和发送发也无需经过连接过程。也就是说,不必调用listen()和accept()函数。UDP中有创建套接字的过程和数据交换的过程。不管是接收方还是发送方都只需要1个套接字。

3.1.1 创建套接字
头文件:

#include <sys/socket.h>

函数原型:

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

参数:

        domain: 网域
        AF_INET : IPv4
        AF_INET6 : IPv6
        type: 选择传输协议 tcp /udp
        SOCK_STREAM ; tcp
        SOCK_DGRAM : udp
        protocol: 基本废弃, 一般赋 0
返回值: 成功返回套接字 fd, 失败返回

3.1.2 bind:绑定自己的IP和端口

发送方:socket   同接收方

函数原型:

ssize_t sendto( 
    int s, //套接字
    const void *buf, //要发送的数据的首地址
    size_t len, //数据的大小
    int flags, // 0
    const struct sockaddr *to,//接收方的 IP 和 port
    socklen_t tolen //上一个参数的大小
);

返回值:成功返回真正发送的数据长度,失败-1

ssize_t recvfrom(
    int s, //套接字
    void *buf, //接受的内容存放的位置的首地址
    size_t len, //接收的大小
    int flags, //0
    struct sockaddr *from, //提供空间即可, 存放发送方的 IP 和 PORT
    socklen_t *fromlen//上一个参数的大小, 但是填指针
);

返回值:成功返回真正接收的数据长度, 失败-1

3.2 广播

udp具有广播功能,即一个发送方,多个接收方;

广播:处于局部网络中的所有设备都可以接收消息

广播的地址:网络号不变,主机号为255 

socket 创建的 UDP 套接字支持组播和广播, 但是想要使用广播, 必须用 setsockopt 设置广播的功能。

接收方:
        1》 创建套接字 socket UDP
        2》 绑定 IP 和 PORT IP 填 INADDR_ANY
        3》 recvfrom 接收

发送方:

        1》 创建套接字 socket UDP
        2》 开启广播功能: setsockopt

开启广播功能函数

int setsockopt(int sockfd,int level,int optname,const void *optval,socklen_t optlen);

函数功能:设置套接字的选项

参数:

sockfd创建的套接字

        level--选项所在的级别:
        想让套接字有广播功能, 就必须把 level 设置为 SOL_SOCKET
                SOL_SOCKET -- 广播功能所在的级别
        optname--选项所在的名称:
                SO_BROADCAST (广播功能)
        optval: 整数的地址
                int num = 1;//开启功能 &num
                0--失能(关闭此功能,系统默认关闭)
                1--使能(开启此功能)
        optlen: optval 的大小 //sizeof(num);

举例:

int a = 1;
setsockopt(fd,SOL_SOCKET,SO_BROADCAST,&a,sizeof(int));

sendto 发送


3.3 多播

对一组特定的主机发送消息 比如: 直播, 多播(D 类), IP 地址分为: 224.0.0.0~239.255.255.255

1》 创建套接字 socket UDP
 

 int setsockopt(int sockfd, int level, int optname,const void *optval, socklen_t optlen);

函数功能: 设置套接字的选项
参数:
        sockfd: socket 创建的套接字
        level: 级别
        SOL_SOCKET : 广播级别
        IPPROTO_IP : 组播级别

        optname: 选项由 level 决定, level 选的是 IPPROTO_IP, optname 有两种选择
        IP_ADD_MEMBERSHIP 加入组播
        IP_MULTICAST_IF 创建组播
        optval: 设置参数 由 optname 决定
        当 optname 为:
                IP_ADD_MEMBERSHIP( 加入组播) , optval 是 struct ip_mreqn 这个结构体
                IP_MULTICAST_IF ( 创建组播) , optval 也是 struct ip_mreqn 这个结构体

struct ip_mreqn
{
    struct in_addr imr_multiaddr;//多播组的地址 224.0.0.0-239.255.255.255 struct
    in_addr imr_address;//本地的 IP 地址, 填固定的宏 INADDR_ANY 即可
    int imr_ifindex; //网卡编号( 物理硬件地址) , 可以用物理硬件 ID 函数:                                                     if_nametoindex("ens33"); 其中 ens33 是网卡的
名字, 通过名字获取编号
};

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

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

相关文章

RockChip Android13 添加/删除ListPreference方法

概述: 本章将讲述在Android添加或删除ListPreference的几种方法,并以EthernetSettingsActivity为例,添加/删除一项ListPreference: 默认效果图: 添加后效果图: 方法一: 1、全部添加xml 在Activity类中使用addPreferencesFromResource()方法解析XML文件并添加Prefere…

OpenHarmony 实战开发——南向统一编译的docker镜像来了

由于我自己的南向设备开发平台的需求&#xff0c;我将当前几个不同的 docker 镜像版本进行了整合&#xff0c;经过一段时间的攻关和验证&#xff0c;目前整合已完成&#xff0c;新版本的 Dockerfile 如下&#xff0c;这个不是公共需求&#xff0c;所以没有提交主干&#xff0c;…

Linux学习笔记4---点亮LED灯(汇编裸机)

本系统学习利用的是正点原子的阿尔法mini开发板&#xff0c;本系列的学习笔记也是按照正点原子的教程进行学习&#xff0c;但并不是利用虚拟机进行开发&#xff0c;而是使用Windows下的子系统WSL进行学习。 因为 Cortex-A 芯片一上电 SP 指针还没初始化&#xff0c;C 环境还没准…

网络安全之弱口令与命令爆破(下篇)(技术进阶)

目录 一&#xff0c;什么是弱口令&#xff1f; 二&#xff0c;为什么会产生弱口令呢&#xff1f; 三&#xff0c;字典的生成 四&#xff0c;九头蛇&#xff08;hydra&#xff09;弱口令爆破工具 1&#xff0c;破解ssh登录密码 2&#xff0c;破解windows登录密码 3&#xf…

新增分类——后端

实现功能&#xff1a; 代码开发逻辑&#xff1a; 页面发送ajax请求&#xff0c;将新增分类窗口输入的数据以json形式提交到服务端服务端Controller接收页面提交的数据并调用Service将数据进行保存Service调用Mapper操作数据库&#xff0c;保存数据 代码实现&#xff1a; Con…

测试项目实战——安享理财1(测试用例)

说明&#xff1a; 1.访问地址&#xff1a; 本项目实战使用的是传智播客的安享理财项目&#xff08;找了半天这个项目能免费用且能够满足测试实战需求&#xff09; 前台&#xff1a;http://121.43.169.97:8081/ 后台&#xff1a;http://121.43.169.97:8082/ &#xff08;点赞收藏…

电脑ip地址设置成什么比较好

随着信息技术的快速发展&#xff0c;IP地址已成为电脑在网络世界中的“身份证”。它不仅是电脑在网络中进行通信的基础&#xff0c;也直接关系到网络连接的稳定性、安全性和效率。然而&#xff0c;面对众多IP地址设置选项&#xff0c;许多用户可能会感到困惑。那么&#xff0c;…

C#进阶-OleDb操作Excel和数据库

在C#编程中&#xff0c;使用OleDb可以方便地实现对Excel文件和数据库的操作。本文探讨了在C#中使用OleDb技术操作Excel和数据库的策略。文章详述了OleDb的定义、配置环境的步骤&#xff0c;并通过实际代码示例演示了如何高效读写Excel文件和交互数据库。文中还评估了OleDb技术的…

5到15秒片头音乐200款,30秒片头音效音乐大全

一、素材描述 本套音乐音效素材&#xff0c;大小2.88G&#xff0c;13个压缩文件。 二、素材目录 200个5到15秒的片头音乐.zip 30秒片头-1.zip 30秒片头-2.zip 30秒片头-3.zip 30秒片头-4.zip 30秒片头-5.zip 30秒片头-6.zip 30秒片头-7.zip 30秒片头-8.zip 30秒片头…

武汉星起航电子商务有限公司助力打造一站式跨境电商服务

在全球电商市场蓬勃发展的当下&#xff0c;武汉星起航电子商务有限公司以其独特的经营模式和全方位的服务体系&#xff0c;成为亚马逊自营领域的佼佼者。自2017年专注于亚马逊自营以来&#xff0c;武汉星起航凭借丰富的经验和深入的市场洞察&#xff0c;为合作伙伴提供了一站式…

生信软件17 - 基于fasta文件的捕获探针设计工具catch

catch是broad研究所开发的一款用于设计捕获探针的python软件。 1. 软件安装 适用于Linux / windows等&#xff0c;安装要求Python≥3.8 | NumPy≥1.22 | SciPy≥1.8.0 # github安装 git clone https://github.com/broadinstitute/catch.git cd catch pip install -e .# coon…

react项目中封装一个通用的边界Boundary

# Boundary 通用的边界,同时是一个Suspense 和一个 ErrorBoundary 正常情况不直接用,使用一下几个封装好的: -Boundary.FullSizeLoading: 占满父容器全部高度,居中显示等待动画; -Boundary.Loading: 占满一行,显示一个普通尺寸的等待动画; -Boundary.Blank: 什么都不显示…

未来编码探索:揭秘Java的进化之旅与技术革新!

Java是一种广泛使用的编程语言&#xff0c;自1995年问世以来&#xff0c;它在企业级应用、移动应用开发、大数据处理等领域都有着广泛的应用。随着时间的推移&#xff0c;Java也在不断发展和进化&#xff0c;以满足不断变化的技术需求和市场趋势。本文将全面详细地探讨Java的未…

Linux 用户进程启动与Systemd

Linux用户空间的启动 我们都知道&#xff0c;Linux在内核的初始化自身的流程结束后&#xff0c;就会将程序流的运行转到用户态&#xff0c;也就是进入init进程流之后&#xff0c;他会按照这个流程进行初始化&#xff1a; init进程初始化 基础的底层服务&#xff1a;比如说ude…

视频号小店怎么开通优选联盟?开通之后有什么好处?

大家好&#xff0c;我是电商糖果 糖果做视频号小店已经快两年时间了&#xff0c;这期间也一直坚持在网上分享自己做店的经验。 这里糖果就来给大家分享一下&#xff0c;视频号小店怎么开通优选联盟&#xff0c;店铺开通之后会有什么好处&#xff1f; 首先我们要知道优选联盟是…

20240509解决Protel99se导入philips.ddb出现File is not recognized的问题

20240509解决Protel99se导入philips.ddb出现File is not recognized的问题 2024/5/9 16:25 缘起&#xff1a;最近需要用到/画PCB&#xff0c;想到十年前用过Protel99SE。 使用的系统&#xff1a;WIN10/WIN11都会出错。WIN7没有测试&#xff01; 从115网盘的角落里找到七集视频…

Objective-C的对象复制与拷贝选项

对象复制与拷贝 文章目录 对象复制与拷贝copy与mutablecopycopy与mutablecopy的简介示例&#xff1a;不可变对象的复制可变对象的复制 NSCopying和NSMutableCopying协议深复刻和浅复刻浅拷贝&#xff08;Shallow Copy&#xff09;&#xff1a;深拷贝&#xff08;Deep Copy&…

【python】将json内解码失败的中文修改为英文(‘utf-8‘ codec can‘t decode,labelme标注时文件名未中文)

出现问题的场景&#xff1a; 语义分割数据集&#xff0c;使用labelme工具进行标注&#xff0c;然后标注图片存在中文名&#xff0c;导致json标签文件写入中文图片名&#xff0c;从而解析失败。 代码解析json文件时&#xff0c;出现报错&#xff1a; python脚本需求&#x…

Java 7大排序

&#x1f435;本篇文章将对数据结构中7大排序的知识进行讲解 一、插入排序 有一组待排序的数据array&#xff0c;以升序为例&#xff0c;从第二个数据开始&#xff08;用tmp表示&#xff09;依次遍历整组数据&#xff0c;每遍历到一个数据都再从tmp的前一个数据开始&#xff0…

论文解读--High-resolution Automotive Radar Point Cloud Imaging and Processing

高分辨汽车雷达点云成像和处理 摘要 汽车雷达具有体积小、硬件成本低、全天候工作、高分辨率等公认的优点&#xff0c;是高级驾驶辅助系统(ADAS)必不可少的一类重要传感器。然而&#xff0c;低角度分辨率和低成像性能的限制很难满足下一阶段ADAS的需要。新兴的4D成像雷达采用多…