linux 网络编程(2) --- socket编程

TCPUDP 常见的错误码 文章目录 在实际TCP&UDP C/S数据收发过程中,常见error code有ECONNABORTED(WSAECONNABORTED),ECONNRESET(WSAECONNRESET),nonblocking io当然还有WOULDBLOCK(WSAWOULDBLOCK)。 ECONNABORTED(WSAECONNABORTED) 该错误被描述为“software caused... 阅读详情

socket编程

套接字的概念

  • socket

  • 在通信过程中,套接字一定是成对出现的

  • 一个文件描述符指向一个套接字,该套接字内部借助两个缓冲区实现,一个用于收,一个用于发

预备知识

网络字节序

小端法(pc本地存储):高位存高地址, 低位存低地址
大端法(网络存储):高位存低地址, 低位存高地址

htonl	本地->网络(ip) 
htons	本地->网络(port)
ntohl	网络->本地(ip)
ntohs	网络->本地(port)
IP地址转换函数
inet_pton函数
作用:将本地的点分十进制的ip字符串转换为一个网络字节序   本地字节序(string IP)->网络字节序
int inet_pton(int af, const char *restrict src, void *restrict dst);
参数:
	af:当前ip版本的
		AF_INET: IPv4
		AF_INET6: IPv6
	src:IP地址(点分十进制)
	dst:传出参数:转换后的网络字节序的ip地址
返回值:
	成功: 1
	异常: 0 说明src指向的不是一个有效的ip地址(即当前的网络中没有这个ip)
	失败: -1, 设置errno
inet_ntop函数
作用:将网络字节序转换为本地的点分十进制的ip		网络字节序->本地字节序(string IP)
const char *inet_ntop(int af, const void *restrict src, char *restrict dst, socklen_t size);
参数:
	af:当前的ip版本
		AF_INET: IPv4
		AF_INET6: IPv6
	src:网络字节序ip地址
	dst:本地字节序
	size:dst的大小
返回值:
	成功:dst
	失败:NULL
sockaddr数据结构
  • 要定义sockaddr_in的数据结构
  • 使用时要强制转换

sockaddr_in 数据结构

struct sockaddr_in {
    sa_family_t    sin_family; /* 用于指定是IPv4还是IPv6*/
    in_port_t      sin_port;   /* 网络字节序的端口号*/
    struct in_addr sin_addr;   /* 网络字节序的IP地址*/
};

/* Internet address */
struct in_addr {
    uint32_t       s_addr;     /* 网络字节序的IP地址 */
};

用法

struct sockaddr_in addr;

addr.sin_family = AF_INET;
addr.sin_port = htons(9527);
// === 法一 ===
int dst;
inet_pton(AF_INET, "192.157.22.42", (void *)&dst);
addr.sin_addr.s_addr = dst;
// === 法二 ===
addr.sin_addr.s_addr = htonl(INADDR_ANY);	//出去当前系统中有效的ip地址(int),并且将其转换为网络字节序

bind(fd, (struct addr*)&addr);
读与写

使用系统调用来读取数据与发送数据

注意

使用read函数的时候

返回值:
	> 0: 实际读到的字节序
	= 0: 表示已经读到了结尾,即对端已经关闭(***)
	< 0: 此时应该进一步判断errno
		errno = EAGAIN 或者是 EWOULDBLOCK 以非阻塞的方式读取数据, 但是没有数据, 需要再次读
		errno = EINTR 慢速系统调用被中断,  需要重启
		errno = ECONNRESET 说明连接被重置->关闭当前的文件描述符
		errno = 其他异常

网络套接字函数

函数作用
socket()创建套接字
bind()绑定IP + port
listen()设置同时监听上限
accept()阻塞监听客户端建立连接
connect()与目标建立连接
socket函数
作用:创建一个套接字
int socket(int domain, int type, int protocol);
参数:
	domain:ip地址协议
		AF_INET
		AF_INET6
		AF_UNIX		本地套接字
	type:数据传输协议
		SOCK_STREAM	流式协议
		SOCK_DGRAM	报式协议
	protocol:所选协议中的代表协议 
		0: 根据type默认选择 流式协议默认为tcp, 报式协议默认为udp
返回值:
	成功:新套接字所对应的文件描述符
	失败: -1, errno
bind函数
作用:给socket绑定一个地址结构(ip + port)
int bind(int sockfd, const struct sockaddr *addr, socklen_t addrlen);
参数:
	sockfd:目标的套接字
	addr:传入参数,被绑定的地址结构(地址结构里的sin_family应该与socket的domain保持一致)
	addrlen: 地址结构的大小
返回值:
	成功:0
	失败:-1,errno
listen函数
作用:设置可以同时进行3次握手的客户端(同时与服务器建立的上限数)
int listen(int sockfd, int backlog);
参数:
	sockfd:目标的套接字
	backlog:上限值,最大值为128
返回值:
	成功:0
	失败:-1,errno
accpet函数
作用:阻塞等待客户端建立连接, 成功的话, 返回一个与客户端成功连接的socket文件描述符
int accept(int sockfd, struct sockaddr *restrict addr, socklen_t *restrict addrlen);
参数:
	sockfd:目标的套接字
	addr:传出参数,成功与服务器建立连接的那个客户端的地址结构
	addrlen:传入传出参数。
		入:addr的大小。
		出:客户端addr的实际的大小
返回值:
	成功:能与服务器进行数据通信的socket对应的文件描述符
	失败: -1, errno
socklen_t client_addr_len = sizeof(addr);
accept(...,..., &client_addr_len);
connect函数
作用:使用现有的socket与服务器建立连接
int connect(int sockfd, const struct sockaddr *addr, socklen_t addrlen);
参数:
	sockfd:目标的套接字
	addr:传入参数,目标服务器的地址结构
	addrlen:服务器地址结构的大小
返回值:
	成功:0
	失败:-1,errno

如果不是用bind绑定客户端地址结构,则采用“隐式绑定”

错误处理函数封装

  • 将系统调用封装成自己的函数
    1. 完成系统调用的工作 2. 检查返回值,查看函数是否正确工作
  • 命名规则:保持与系统调用相同的命名规则, 可以将首字母大写

实现目标:

  1. 功能一样
  2. 不用进行错误判断

多进程并发服务器

设计思路

  1. Socket() 创建监听套接字

  2. Bind() 绑定地址结构

  3. Listen()

  4. while(1) {
    cfd = Accpet(); 接受客户端连接请求
    pid = fork();

    if (pid == 0) { 子进程: read() – 处理 — write()
    close(lfd) 关闭用于建立连接的套接字lfd
    while(1){ … } 处理
    } else if (pid > 0) { 父进程
    close(cfd) 关闭用于与客户端通信的套接字
    {…} 用于回收子进程的函数
    continue;
    }
    }

  5. 子进程:

    close(lfd)
    read()
    { ... }  一系列动作
    write()
    

    父进程:

    注册信号捕捉函数:		SIGCHLD
    在回调函数中,完成子进程回收	while(waitpid())
    

多线程并发服务器

设计思路

  1. Socket() 创建监听套接字

  2. Bind() 绑定地址结构

  3. Listen()

  4. while(1) {

    cfd = Accept(lfd);

    pthread_create(&tid, NULL, tfn, NULL);

    pthread_detach(tid) 不获取线程的值// pthread_join(tid, void **) 获取线程的值, 为了防止线程阻塞, 可以新开一个线程来回收

  5. 子线程:

    void *tfn(void *arg) {

    ​ close(lfd);

    ​ read(cfd)

    ​ 功能

    ​ write(cfd)

    }

#include <stdlib.h>
#include <unistd.h>
#include <pthread.h>
#include <stdio.h>
#include <errno.h>
#include <string.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <ctype.h>


void sys_err(const char * str);

int Socket(int domain, int type, int protocol);
int Bind(int socket, const struct sockaddr_in *address, socklen_t address_len);
int Listen(int sockfd, int backlog);
int Accept(int socket, sockaddr_in *address, socklen_t *address_len);
int Connect(int socket, const struct sockaddr_in *address, socklen_t address_len);

void thread_error(const char * message);

void sys_err(const char *str)
{
    perror(str);
    exit(1);
}

int Socket(int domain, int type, int protocol)
{
  int n;
  n = socket(domain, type, protocol);
  if (n == -1)
  {
    sys_err("socket error");
  }

  return n;
}

int Bind(int socket, const struct sockaddr_in *address, socklen_t address_len)
{
  int n;
  n = bind(socket, (struct sockaddr *)address, address_len);
  if (n == -1)
  {
    sys_err("bind error");
  }
  return 0;
}

int Listen(int sockfd, int backlog)
{
  int ret = listen(sockfd, backlog);
  if (ret == -1)
  {
    sys_err("listen error");
  }
  return 0;
}

int Accept(int socket, struct sockaddr_in *address, socklen_t *address_len)
{
  int n;
  n = accept(socket, (struct sockaddr *)address, address_len);
  if (n == -1)
  {
    sys_err("accept error");
  }
  return n;
}

int Connect(int socket, const struct sockaddr_in *address, socklen_t address_len)
{
  int ret;
  if ((ret = connect(socket, (struct sockaddr *)address, address_len)) == -1)
  {
    sys_err("connect error");
  }
  return ret;
}

void thread_error(const char *message)
{
  fprintf(stderr, "%s\n", message);
}


struct s_info
{
    sockaddr_in s_addr;
    int fd;
} ts[256];

const int BUFSIZE = 1024;

void *connect_client(void *arg)
{
    struct s_info *ts = (struct s_info *)arg;
    ssize_t size_len = 0;
    char buf[BUFSIZE];
    while (1)
    {
        size_len = read(ts->fd, buf, BUFSIZE);
        if (size_len == 0)
        {
            close(ts->fd);
            pthread_exit(NULL);
        }
        for (int i = 0; i < size_len; i++)
        {
            buf[i] = toupper(buf[i]);
        }
        write(ts->fd, buf, size_len);
    }
}

int main(int argc, char **argv)
{
    int server_socket = Socket(AF_INET, SOCK_STREAM, 0);

    int opt = 1;
    setsockopt(server_socket, SOL_SOCKET, SO_REUSEADDR, (void *)&opt, sizeof(opt));

    sockaddr_in addr, client;
    socklen_t len = sizeof(client);

    addr.sin_addr.s_addr = htonl(INADDR_ANY);
    addr.sin_family = AF_INET;
    addr.sin_port = htons(443);

    Bind(server_socket, &addr, sizeof(addr));

    Listen(server_socket, 127);

    int i = 0;
    while (1)
    {
        int client_fd = Accept(server_socket, &client, &len);

        ts[i].s_addr = client;
        ts[i].fd = client_fd;

        pthread_t tid;
        pthread_create(&tid, NULL, connect_client, (void *)&ts[i]);
        pthread_detach(tid);
        i++;
    }
    return 0;
}

端口复用

  • 即创建端口号相同, 但是ip地址不同的socket(一般用在断开了连接,但是没有完全断开的情况),比如快速重启服务器
  • 在socket() 和bind()之间插入代码
int opt = 0 / 1;			// 0为不复用(默认), 1为复用
setsockopt(lfd, SOL_SOCKET, SO_REUSEADDR, (void *)&opt, sizeof(opt))
errno错误对照表 错误对照表: 错误值 内容 errno 0 : Success 成功 errno 1 : Operation not permitted 不允许操作 errno 2 : No such file or directory 没有这样的文件或目录 errno 3 : No such process 没有这样的过程 errno 4 : Interrupted system call 中断的系统调用 errno 5 : Input/output error 输入/输出错误 阅读详情

相关推荐

ESP-IDF OTA升级过程中遇到的“esp_transport_read returned:-1 and errno:128”问题(2)

ESP-IDF OTA升级过程中遇到的“esp_transport_read returned:-1 and errno:128”问题(2)

phmatthaus的专栏 687

TCP/IP 某些最常见的错误原因码 (errno)列表(转)

对于在基于 UNIX 的环境中的 TCP/IP 用户,下表列出了某些最常见的错误原因码 (errno)。它不是完整的错误列表。可以在文件 /usr/include/sys/errno.h 中找到 Errno。针对每一种操作系统给出了errno 号码。 基于 UNIX 的 TCP/IP errno Errno Errno号码 AIXHP-UXSolarisUnixWareLinux ...

weixin_33970449的博客 1237

[Ethernet in CANoe]3--CANoe工程中SOME/IP报文的详细介绍(一)

和上述第一章节的介绍,我们对SOEMIP通信协议有了初步了解,首先我们先暂停Trace窗口,可以看到整个Trace窗口关于SOMEIP的报文有两种颜色,一种是紫色,另一种是绿色。它使用多播地址,允许服务提供者发布其服务,服务消费者订阅这些服务。上述每点开一个SOMEIP报文,左侧的details就能看到该报文中的具体细节,从IP地址到port口,再到具体的serviceID,都能详细的解析。一旦通过服务发现完成了服务的发布和订阅,服务消费者就可以向服务提供者发送请求,或者服务提供者向消费者发送事件通知。

汽车ECU自动化测试 1412

errno错误码及含义(中文)

https://www.cnblogs.com/pengdonglin137/p/3326460.html

dp__mcu的专栏 1万+

Dev-C++使用技巧2(亲测)(更改字体和颜色、自动保存、快捷键选项、一键排版)

更改字体和颜色 顶部菜单栏->工具->编辑器选项。 更改字体 当前选项卡->显示,字体word有的基本都有,华文楷体、宋体,幼圆之类。西文字体默认字体Consloas就不错,中文的话幼圆、新宋体都挺不错。 幼圆效果: 新宋体效果: 更改颜色 当前选项卡->语法,分别单击图中的部分,然后在左边修改前景颜色就可以了。需要直接显示的修改前景颜色,背景颜色设为白色;需要选中显示的修改背景颜色,前景设为白色。 自动保存 我们有时候忘记保存或者电脑突然关机,可能会丢失代码。

魔神之云的博客 2万+

从零开始学习信号完整性(SIPI)--2

上一节我们已经谈过,信号完整性研究的是如何使驱动器输出的信号传输到接收器件并被正确的接收。 信号完整性的三要素包含了:信号、驱动接收芯片、传输通道。 这其中信号是主体,我们要做的主要工作就是设计好信号的传输路径为信号的正确传输扫清障碍。要做信号完整性分析与设计首先要了解信号的特性,以及信号质量的判别标准。 对一个信号进行描述通常需要如下几个指标: 信号特性的描述 摆幅:信号从低电平到高电平之间的电压差,对于单端信号通常由信号的供电电压决......

qq_29476769的博客 2万+

Linux网络编程2——socket编程

类似于管道文件。一个文件描述符指向一个套接字(套接字内部由内核提供两个缓冲区实现)在通信过程中,套接字一定是成对出现的(Linux主机上有,客户端主机上也有)1、函数为使网络程序具有可移植性,使同样的C代码在大端和小端计算机上编译后都能正常运行,可以调用以下库函数做网络字节序和本地字节序的转换htonl本地字节序——>网络字节序(32位,主要转换的是IP)htons本地字节序——>网络字节序(16位,主要转换的是port)ntohl2、对上面函数进行封装。......

HuanBianCheng27的博客 1433

【C语言】字符常量详解

字符常量是C语言中处理字符数据的重要工具。通过单引号括起一个字符,我们可以方便地使用字符常量进行字符判断、字符运算和字符串处理等操作。理解字符常量的表示方法、使用场景和ASCII码对应关系,对于编写高效的C语言程序至关重要。

LuckiBit 5021

Linux网络编程2-socket编程

一. 网络套接字: 套接字就是socket,socket就像网络两端的两个站点,他们之间的要走的路就是数据传输的线路。套接字会标识进程的ip和端口号,其实就标识了主机和里面那个进程(程序)。网络套接字是一个文件,用文件描述符表示。 在网络通信中,套接字一定是成对出现的。一端的发送缓冲区对应对端的接收缓冲区。我们使用同一个文件描述符索发送缓冲区和接收缓冲区。 二. 数据转化 1. 网络字节序 小端法:(pc本地存储) 高位存高地址。地位存低地址。 int a = 0x12345678大端法:(网络存储) 高

qq_40888486的博客 342

Cesium中级开发教程之五十二:气泡弹窗

支持多种交互方式触发气泡弹窗显示,如鼠标悬停、点击地图上的特定元素(像实体、标注、模型等)。例如,当用户鼠标悬停在一个表示城市的点上时,弹出显示该城市名称、人口等信息的气泡。:依据特定的数据条件或业务逻辑触发。比如,当某个区域的气象数据达到一定阈值时,自动弹出显示相关气象预警信息的气泡。

664

3D点云-CVPR 2020-PF-Net: Point Fractal Network for 3D Point Cloud Completion

是一种专门为三维点云补全设计的深度学习模型。点云补全实际上和图片补全是一个逻辑,都是采用GAN模型的思想来进行补全,在图片补全中,将部分像素点删除并且标记,然后卷积特征提取预测、判别器判别,来训练模型,生成的像素点与原来像素点比较完成模型的训练。而PF-Net就是采用GAN的思想在3D点云上的应用。

404 Not Found 2373

linux系统编程2--网络编程socket知识

连接协议(socket):函数原型:int socket(int domain, int type, int protocol);参数1int domain:指明所使用的协议,通常为AF_INET,表示互联网协议族(TCP/IP协议族);(AF_INET—IPv4因特网域、AF_INET6—IPv6因特网域、AF_UNIX—Unix域、AF_ROUTE—路由套接字、AF_KEY—密钥套接字、AF_UNSPEC—未指定)参数2int type:指定socket的类型;

hqwest的专栏 587

第14.1章 高翔博士2025年11月最新开源框架Lightning-LM源码学习解读(一):激光-IMU定位+建图算法各模块简介

Lightning-LM:高效激光SLAM定位系统 该框架基于模块化设计,通过激光-IMU融合实现快速建图与定位,核心特点包括: 极速性能:纯CPU运行(建图1.2核/定位0.8核) 模块化架构:包含激光里程计(LIO)、地图管理、回环检测等独立模块 动态场景支持:地图分块加载、动静态图层分离 多模式适配:支持ROS2环境下的在线/离线运行 关键模块包括前端里程计(core/lio)、2D/3D地图转换(core/g2p5)、轻量优化库(core/miao)等,通过系统控制器(core/system)协调流

行知SLAM 2439

linux网络编程socket通信2

原理:原函数和包裹函数的函数名差异只有首字母大写,这是因为man page对字母大小写不敏感,同名的包裹函数一样可以跳转至man page , 新包裹需要检查返回值的函数,让代码不那么肥胖。在接收和发送数据时个人设计一个守护进程(线程),定时发送Heart-Beat包,客户端/服务器收到该小包后,立刻返回相应的包即可检测对方是否实时在线。为了实时检测查询的链接状态,常用的方法就是加入心跳机制。

weixin_45205160的博客 588

国科大学习资料--VLSI测试与可测试设计--2020期末考试试题

国科大学习资料–VLSI测试与可测试设计–2020期末考试试题 国科大学习资料–VLSI测试与可测试设计–2020期末考试试题 国科大学习资料–VLSI测试与可测试设计–2020期末考试试题 一、概念题 1简述可测试性测度与两个主要的测度指标的含义; 2以March C-算法为例,说明March算法的构成,以及March C-算法的故障覆盖率; 3“效果-原因”诊断法和“原因效果诊断法”的不同; 4列举四条扫描设计时出现的问 题及解决办法; 5最少写出1149.1与1500的五点不同; = = = = =

无名何许人的博客 1150

IEM模型,地表粗糙度模拟

利用微波反演土壤水分时候,利用IEM模型可以实现对随机地表的模拟

linux 网络编程(2)socket网络编程

基础 地址 地址由IP地址、端口号构成 IP地址:用于设备标识 端口号:用于标识网络服务(ftp、http、socket) (5000到10000之间选择) IP地址转换API(IP地址是字符串要转换成网络能识别格式) #include <sys/socket.h> #include <netinet/in.h> #include <arpa/inet.h> int inet_aton(const char *cp, struct in_addr *inp); //

cyh20001027的博客 273

jre9下载 jdk9

(Java SE Runtime Environment 9.0) 9.0u175 官方最新版 【x86|x64】

《Linux网络编程》2.Socket编程(UDP/TCP)

本文介绍了基于C++的UDP和TCP网络编程实现。主要内容包括:1)UDP编程的核心接口(socket、bind、send/recv)及C++封装实现UDPServer类;2)TCP编程的关键接口(listen、accept、connect)及TCPServer类的封装,包含InetAddr地址处理类;3)分别给出了UDP和TCP的客户端与服务器实现示例代码。文章重点阐述了两种协议的网络编程实现差异,并通过面向对象方式对底层系统调用进行封装,提升了代码复用性和可维护性。最后指出当前TCPServer实现存在

qq_49648783的博客 1499

SAP B1中文培訓教材_SDK

公司内部培训资料,对开发工具 ,DIAPI, UIAPI,Add-ON有详细解说

efm32 入门.pdf

本PDF共计22页,介绍的是操作驱动API,下载与否自己斟酌。

Linux学习之网络编程2(socket,简单C/S模型)

Linux网络编程系列的第二篇。主要介绍了套接字socket,把上一章的理论应用到实践中,介绍了怎么建立网络通信,分别从语法,功能,参数,返回值多个方面详细讲解了建立通信的几个函数。最后写了个小demo,建立简单C/S模型来把上面学的知识学以致用,附有完整源代码。

yourgrandfather_的博客 1277

Linux 网络编程笔记(2)——socket 编程

socket 可以看作是用户进程与内核网络协议栈的编程接口 既可以用于本机的进程间通信,还可以用于网络上不同主机的进程间通信 listenfd 是被动套接字,可以用来接受连接。 accept 从已完成连接队列中取出一个队列头,得到一个新套接字 connfd。 connfd 是主动套接字,不能用来接受连接。 服务端和客户端的 ip 和 port 四元组表示 一个连接。 REUSEADDR 可以解决

ize 507

【Linux网络编程】2. Socket编程 UDP

本文介绍了Socket编程中UDP的应用,实现了回显服务、翻译服务、聊天室服务等等内容。

2301_80475881的博客 431

基于VS2019 C++的跨平台(Linux)开发(2.2)——SOCKET网络编程

socket概述 为了简化开发通信程序的工作,由Berkely学校开发了一套网络通信程序的API函数标准 socket标准被扩展成window socket和unix socket linux中的网络编程通过socket接口实现。Socket既是一种特殊的IO,它也是一种文件描述符。一个完整的Socket 都有一个相关描述{协议,本地地址,本地端口,远程地址,远程端口};每一个Socket 有一个本地的唯一Socket 号,由操作系统分配。 ...

hml111666的博客 5512

linux网络编程 socket常用函数(2)

======== TCP======== TCP_Server socket() bind() listen() accept() write() read() close() 和shutdown() TCP_Client socket() connect() send() 和recv() close() 和shutdown() ======== UDP======== UDP_Server socket() bind() sendto() 和recvfrom(...

qinjie的博客 261

linux c++ socket 网络编程(2) select 异步非阻塞

1.3. 多路复用 上面的方法可以完成单个线程处理多个socket读写的。但这样的轮询方式,一定无法应付大量的请求,因为效率太低了,仅处理网络IO就要消耗掉大量的CPU资源,这是十分不可取的。 那所谓的多路复用,就是要解决低效的问题。个人理解复用,就是将多个低速率的流,合成一个高速率的流,来达到提高利用率的目的。放在网络编程模型里的多路复用,就是将多个低速的网络IO流,合成一个高速的网络IO流

wenrenwang的专栏 4306

Linux网络编程:Socket编程接口(2)TCP下的网络编程

文章目录3. 完成TCP网络编程3.1 完善3.2 属性3.3 多个客户端的和单个服务器通信3.4 代码格式化工具astyle 3. 完成TCP网络编程 三次挥手的阶段: 四次挥手的阶段: 3.1 完善 从终端输入 ip 地址和端口号,使用 int argc 和 char* argv[] 需要多条信息的发送和接收,使用无限循环 为了不受输入堵塞的影响,让客户端和服务器之间多发消息,收发信息用各自的进程 客户端开一个进程,让父进程写子进程读 服务器也开一个进程,让父进程读子进程写 (或者用线程 threa

凯凯在此 430

Linux操作系统 - 网络编程socket(2)

网络通信socket之tcp通信实现过程

weixin_43164548的博客 2629

C/C++ Linux网络编程2 - Socket编程与简单UDP服务器客户端

摘要:本文介绍了Linux下UDP网络编程的基础知识,重点讲解了Socket编程API和结构体的使用方法。文章详细说明了sockaddr、sockaddr_in和sockaddr_un三种结构体的区别及应用场景,并通过C++类封装实现了UDP服务端和客户端的完整代码。服务端需要绑定IP和端口,使用recvfrom接收数据;客户端则通过sendto发送数据,无需显式绑定端口。最后提供了本地回环地址127.0.0.1的测试方法,展示了完整的通信流程。

yzc的博客 1031
上一篇: linux 网络编程(1) --- 网络基础
下一篇: linux 网络编程(3) --- 高并发服务器
ghost_him
博客等级 码龄6年 598粉丝 90原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值