单线程消息发送接收

This commit is contained in:
flykhan 2023-03-31 16:43:54 +08:00
parent 8d04136288
commit 23edc547eb
5 changed files with 480 additions and 7 deletions

3
.gitignore vendored
View File

@ -331,4 +331,5 @@ Temporary Items
!.gitsubmodules !.gitsubmodules
*.s *.s
/debug /debug
/test /test
*/test

118
Experiment_1/README.md Normal file
View File

@ -0,0 +1,118 @@
# 头文件说明
### sys/types.h
> sys/types.h是一个头文件定义了一些基本的系统数据类型和结构体。它通常被包含在其他系统头文件中比如socket.h、unistd.h等等。
>
> 在这个头文件中,定义了一些重要的数据类型,例如:
>
> - size_t表示无符号整型数用于存储对象的大小。
> - ssize_t表示有符号整型数用于存储一些系统调用返回值的大小和状态。
> - pid_t表示进程ID用于标识当前进程或者其他进程。
> - off_t表示文件偏移量用于指示文件中的位置。
> - time_t表示时间戳用于记录某个事件发生的时间。
> - mode_t表示文件权限掩码用于定义文件的读写执行权限等信息。
>
> 除此之外sys/types.h还定义了一些与文件描述符、信号、套接字等相关的结构体。这些结构体包括fd_set、sigevent、itimerval、timespec等等可用于进行多路复用、事件驱动等高级操作。
>
> 总之sys/types.h是一个非常重要的头文件在系统编程和网络编程中经常被使用。通过定义各种基本数据类型和结构体它为程序员提供了方便的系统级别的访问接口使得开发更加高效和灵活。
### sys/socket.h
> sys/socket.h是一个C语言标准库头文件它提供了访问底层套接字接口的函数和数据类型。在网络编程中我们使用这个头文件来创建、绑定、监听、连接、发送和接收套接字等操作。
>
> 该头文件中定义了一系列函数原型包括socket、bind、listen、connect、send、recv等等套接字相关的函数以及sockaddr、sockaddr_in等结构体类型用于表示套接字地址信息。这些函数和结构体提供了基本的套接字操作可以实现客户端和服务器之间的数据交换和通信。
>
> 除此之外sys/socket.h还定义了一些常量和枚举类型例如SOCK_STREAM、SOCK_DGRAM等用于指定套接字的类型和传输协议。这些常量和枚举类型可以帮助程序员更方便地控制套接字的行为和参数。
>
> 总之sys/socket.h是网络编程中一个非常重要的头文件通过提供各种函数和数据类型使得程序员能够方便地进行底层套接字操作实现可靠的网络通信。
### stdio.h
> stdio.h是一个C语言标准库头文件提供了输入和输出相关的函数和数据类型。在C程序中我们通常需要使用stdio.h来实现各种控制台输入输出操作也包括一些文件读写等相关操作。
>
> 该头文件中定义了一系列函数原型包括printf、scanf、puts、gets等等标准输入输出函数。这些函数可以帮助我们向屏幕输出信息、从键盘获取用户输入实现基本的控制台输入输出功能。
>
> 除此之外stdio.h还定义了FILE结构体类型用于表示文件流。通过使用fopen、fclose、fprintf、fscanf等函数我们可以对文件进行读写操作并指定相应的文件名、打开模式、读写位置等参数。
>
> 总之stdio.h是一个非常常用的标准库头文件在C程序中几乎都会被用到。它提供了各种方便的输入输出函数和数据类型可以帮助我们实现控制台交互、文件操作等各种功能。
### netinet/in.h
> netinet/in.h是一个C语言标准库头文件主要用于定义网络通信中的地址族、套接字地址结构体等相关信息。在网络编程中我们使用这个头文件来创建和处理IPV4和IPV6地址等操作。
>
> 该头文件中定义了一系列数据类型和结构体包括sockaddr_in、sockaddr_in6、in_addr等类型以及各种基本数据类型如uint16_t、uint32_t等。这些数据类型和结构体可以帮助我们创建、表示和传递套接字地址信息进行网络通信。
>
> 除此之外netinet/in.h还定义了一些常量和枚举类型例如IPPROTO_TCP、IPPROTO_UDP等用于指定套接字的传输协议或其他相关参数。通过这些常量和枚举类型我们可以更加方便地控制套接字的行为和配置。
>
> 总之netinet/in.h是网络编程中一个非常重要的头文件通过定义各种数据类型、结构体、常量和枚举类型它为程序员提供了方便的接口使得开发网络应用变得更加高效和简单。
### arpa/inet.h
> #include <arpa/inet.h> 是一个C语言标准库头文件提供了一系列用于IP地址转换的函数包括将点分十进制IP地址转换为二进制IP地址、将二进制IP地址转换为点分十进制IP地址等操作。
>
> 该头文件中定义了一些函数原型包括inet_addr、inet_ntoa、inet_pton、inet_ntop等函数。其中inet_addr函数用于将点分十进制IP地址转换为32位无符号整数inet_ntoa函数用于将32位无符号整数表示的IP地址转换为点分十进制字符串inet_pton函数和inet_ntop函数用于进行IPv4和IPv6地址之间的转换。
>
> 除此之外,<arpa/inet.h> 还定义了一些与网络字节序big-endian和主机字节序little-endian有关的函数包括htons、htonl、ntohs、ntohl等。这些函数可以帮助我们在不同主机上正确地解析网络数据并保证通信的正确性和可靠性。
>
> 总之,<arpa/inet.h> 是网络编程中一个非常重要的头文件通过提供方便的IP地址转换函数以及网络字节序相关的函数它使得程序员能够更加方便地处理网络通信中各种复杂的字节序和地址转换问题。
### unistd.h
> unistd.h是一个C语言标准库头文件提供了一些UNIX系统调用相关的函数和符号常量。在Unix/Linux操作系统下我们通常需要使用unistd.h来实现各种系统级别的操作例如进程控制、文件IO、系统资源管理等。
>
> 该头文件中定义了一系列函数原型包括read、write、close、fork、execve等函数。这些函数可以帮助我们进行文件读写操作、进程创建和替换、信号处理等操作。
>
> 除此之外unistd.h还定义了一些符号常量例如STDIN_FILENO、STDOUT_FILENO、STDERR_FILENO等用于表示标准输入输出文件描述符方便程序员进行输入输出操作。同时它还定义了一些与系统路径、进程限制、系统资源等相关的常量和变量例如PATH_MAX、_SC_OPEN_MAX、sysconf等等。
>
> 总之unistd.h是一个非常重要的头文件在Unix/Linux编程中经常被使用。通过提供各种系统调用函数和符号常量它为程序员提供了方便的系统级别的访问接口使得开发更加高效和灵活。
### string.h
> string.h是一个C语言标准库头文件提供了一系列字符串相关的函数和数据类型。在C程序中我们通常需要使用string.h来实现各种字符串操作如字符串拷贝、字符串比较、字符串搜索等。
>
> 该头文件中定义了一系列函数原型包括strcpy、strncpy、strlen、strcmp、strncmp、strstr等函数。这些函数可以帮助我们进行字符串操作如复制、比较、查找等等。同时也定义了一些与内存管理相关的函数如memset、memcpy、memmove等。
>
> 除此之外string.h还定义了一些基本数据类型例如size_t等用于表示字符串长度等信息。
>
> 总之string.h是一个非常重要的标准库头文件在C程序中经常被使用。通过提供各种字符串操作函数和相关数据类型它为程序员提供了方便的接口使得开发更加高效和灵活。
### stdlib.h
> stdlib.h是一个C语言标准库头文件提供了一些与内存分配、程序终止、随机数生成等相关的函数和数据类型。在C程序中我们通常需要使用stdlib.h来实现各种动态内存分配、异常处理、程序退出等操作。
>
> 该头文件中定义了一系列函数原型包括malloc、calloc、realloc、free等函数。这些函数可以帮助我们进行内存管理如申请动态内存、释放动态内存等。同时也定义了一些与异常处理相关的函数如exit、abort等。
>
> 除此之外stdlib.h还定义了一些基本数据类型例如size_t、div_t、ldiv_t等用于表示整数、浮点数等信息。同时它还提供了一些随机数生成相关的函数如rand、srand等。
>
> 总之stdlib.h是一个非常重要的标准库头文件在C程序中经常被使用。通过提供各种内存分配、异常处理和随机数生成函数以及相关数据类型它为程序员提供了方便的接口使得开发更加高效和灵活。
### fcntl.h
> fcntl.h是一个C语言标准库头文件主要用于处理文件描述符。在Unix/Linux系统下我们通常需要使用fcntl.h来实现各种文件操作如文件锁、文件状态标志等。
>
> 该头文件中定义了一系列函数原型包括fcntl、open、creat、flock等函数。这些函数可以帮助我们打开和关闭文件、控制文件状态等。此外它还定义了一些与文件锁相关的数据类型和常量例如flock、F_RDLCK、F_WRLCK等用于实现文件锁定和解锁操作。
>
> 除此之外fcntl.h还定义了一些与信号处理和进程控制有关的常量和函数例如F_SETOWN、F_GETLK、sigaction等。这些常量和函数可以帮助我们实现对进程和信号的控制。
>
> 总之fcntl.h是一个非常重要的头文件在Unix/Linux编程中经常被使用。通过提供各种文件描述符相关的函数和常量、以及信号处理、进程控制等相关接口它为程序员提供了方便的访问接口使得开发更加高效和灵活。
### sys/shm.h
> sys/shm.h是一个C语言标准库头文件主要用于实现共享内存操作。在Unix/Linux操作系统下我们通常需要使用sys/shm.h来实现各种进程间的数据交换和共享内存访问。
>
> 该头文件中定义了一系列函数原型包括shmget、shmat、shmdt、shmctl等函数。这些函数可以帮助我们创建共享内存区、将共享内存区附加到进程空间、解除共享内存区的附加、控制共享内存区的属性等。
>
> 除此之外sys/shm.h还定义了一些与共享内存相关的结构体和常量例如shmid_ds、SHM_RDONLY、IPC_CREAT等用于表示共享内存的元信息和参数配置。
>
> 总之sys/shm.h是一个非常重要的头文件在Unix/Linux编程中经常被使用。通过提供各种共享内存操作函数和相关结构体它为程序员提供了方便的接口使得开发进程间的数据交换和共享内存访问变得更加高效和灵活。
### iostream
> iostream是一个C++标准库头文件提供了输入输出流相关的类和函数。在C++程序中我们通常需要使用iostream来实现各种控制台输入输出操作、文件读写操作等。
>
> 该头文件中定义了两个基本的C++流对象cin和cout分别用于从控制台读取用户输入和向控制台输出信息。除此之外iostream还提供了一些其他的流对象和类包括cerr、clog、ifstream、ofstream等用于表示错误输出、日志输出、文件输入和输出等。
>
> 除此之外iostream还定义了一些流操作符和流缓冲区的设置如endl、setw等。通过这些操作符和设置我们可以更方便地控制流的输出格式和行为。
>
> 总之iostream是一个非常重要的C++标准库头文件在C++程序中经常被使用。通过提供各种输入输出流相关的类和函数,它为程序员提供了方便的接口,使得开发控制台交互、文件读写等各种功能变得更加高效和灵活。

48
Experiment_1/client.cpp Normal file
View File

@ -0,0 +1,48 @@
#include <sys/types.h>
#include <sys/socket.h>
#include <stdio.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <string.h>
#include <stdlib.h>
#include <fcntl.h>
#include <sys/shm.h>
#include <iostream>
using namespace std;
int main()
{
// 定义客户端 sockfd 套接字描述符
int sock_cli = socket(AF_INET, SOCK_STREAM, 0);
// 定义 sockaddr_in
struct sockaddr_in servaddr;
memset(&servaddr, 0, sizeof(servaddr));
servaddr.sin_family = AF_INET; // TCP/IP 协议族
servaddr.sin_port = htons(8023); // 服务器端口
servaddr.sin_addr.s_addr = inet_addr("127.0.0.1"); // 服务器 ip
// connect 同远程服务器建立主动连接成功时返回0若连接失败返回1
if (connect(sock_cli, (struct sockaddr *)&servaddr, sizeof(servaddr)) < 0)
{
perror("connect");
exit(1);
}
cout << "连接服务器成功!\n";
char sendbuf[100]; // 发送缓冲数组
char recvbuf[100]; // 接收缓冲数组
while (1)
{
memset(sendbuf, 0, sizeof(sendbuf));
cin >> sendbuf; // 向发送缓冲数组写入数据
send(sock_cli, sendbuf, sizeof(sendbuf), 0); // 发送数据
if (strcmp(sendbuf, "exit") == 0)
break; // 如果发送字符为exit则跳出发送循环
}
close(sock_cli); // 关闭发送套接字描述符
return 0;
}

76
Experiment_1/server.cpp Normal file
View File

@ -0,0 +1,76 @@
#include <sys/types.h>
#include <sys/socket.h>
#include <stdio.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <string.h>
#include <stdlib.h>
#include <fcntl.h>
#include <sys/shm.h>
#include <iostream>
using namespace std;
int main()
{
// 定义服务端 sockfd (套接字描述符)
int server_sockfd = socket(AF_INET, SOCK_STREAM, 0);
// 定义服务端套接字 sockaddr_in (套接字地址结构)
struct sockaddr_in server_sockaddr;
server_sockaddr.sin_family = AF_INET; // TCP/IP 协议族
server_sockaddr.sin_port = htons(8023); // 端口号
server_sockaddr.sin_addr.s_addr = inet_addr("127.0.0.1"); // ip 地址127.0.0.1 是回环地址,相当于本机 ip
// bind (功能:为套接字绑定地址) 绑定成功返回 0 ,绑定出错返回 -1
if (bind(server_sockfd, (struct sockaddr *)&server_sockaddr, sizeof(server_sockaddr)) == -1)
{
perror("bind"); // 输出错误原因
exit(1); // 结束程序
}
// listen (将一个套接字置为监听模式,准备接收传入连接。用于服务器,指明某个套接字连接是被动的监听状态)
// 成功返回 0 ,出错返回 -1
if (listen(server_sockfd, 20) == -1)
{
perror("listen"); // 输出错误原因
exit(1); // 结束程序
}
// 客户端套接字
struct sockaddr_in client_addr;
socklen_t length = sizeof(client_addr);
// accept (功能:从已完成连接队列中取出成功建立连接的套接字,返回成功连接的套接字描述符)
// 成功返回非负描述符,出错返回 -1
int conn = accept(server_sockfd, (struct sockaddr *)&client_addr, &length);
if (conn < 0)
{
perror("connect"); // 输出错误原因
exit(1); // 结束程序
}
cout << "客户端成功连接\n";
// 接收缓冲区:定义为 1000 字节大小,最多存储 999 个字符长度的字符串,最后一个字符要留给'\0'
char buffer[1000];
// 不断接收数据
while (1)
{
// memset函数有三个参数第一个参数是要被初始化的内存区域的起始地址第二个参数是要设置的值第三个参数是要初始化的字节数
memset(buffer, 0, sizeof(buffer));
// recv (功能:接收数据,返回实际接收的数据长度出错时返回1)
int len = recv(conn, buffer, sizeof(buffer), 0);
// 客户端发送 exit 或者异常结束时,退出
if (strcmp(buffer, "exit") == 0 || len <= 0)
break;
cout << "收到客户端信息:" << buffer << endl;
}
// 套接字通常需要在完成数据传输等操作后及时关闭,以释放系统资源并避免出现一些问题,比如资源耗尽、端口占用等
// conn和server_sockfd分别表示客户端和服务器端的套接字文件描述符通过调用close函数来关闭它们
close(conn); // 关闭数据接受描述符
close(server_sockfd); // 关闭套接字
return 0;
}

242
README.md
View File

@ -1,10 +1,240 @@
- #### C++ 编译过程 ## C++ 编译过程
首先我们要明确在 C++ 中编译过程分为四个阶段:预处理、编译、汇编、链接: 首先我们要明确在 C++ 中编译过程分为四个阶段:预处理、编译、汇编、链接:
- 预处理阶段主要负责宏定义的替换、条件编译、将 include 的头文件展开到正文等; - 预处理阶段主要负责宏定义的替换、条件编译、将 include 的头文件展开到正文等;
- 编译阶段负责将源代码转为汇编代码; - 编译阶段负责将源代码转为汇编代码;
- 汇编阶段负责将汇编代码转为可重定位的目标二进制文件; - 汇编阶段负责将汇编代码转为可重定位的目标二进制文件;
- 链接阶段负责将所有的目标文件(二进制目标文件、库文件等)连接起来,进行符号解析和重定位,最后生成可执行文件。 - 链接阶段负责将所有的目标文件(二进制目标文件、库文件等)连接起来,进行符号解析和重定位,最后生成可执行文件。
## 服务器和客户端进行简单的 TCP 通信
### 传输层的基本概念
![图片描述](https://typoraflykhan.oss-cn-beijing.aliyuncs.com/202303301348031.jpeg)
#### 传输层的作用
传输层的根本目的是在网络层提供的数据通信服务基础上,实现主机的进程间通信的可靠服务。
有以下两个要点:为位于两个主机内部的两个应用进程之间提供通信服务、提供可靠的通信服务。
#### 套接字
“套接字”表示一个 IP 地址与对应的一个端口号。例如,一个 IP 地址为 172.31.75.8 的客户端使用 8050 端口号那么标识客户端的套接字为“172.31.75.8:8050”。
#### 端口号
端口号为 0-65535 之间的整数,有 3 种类型:熟知端口号、注册端口号、临时端口号。
熟知端口号:给每种服务器分配确定的全局端口号。每个用户进程都知道相应的服务器进程的熟知端口号,范围为 0-1023它是统一分配和控制的。
注册端口号:在 IANA 注册的端口号,数值范围为 1024-49151。
临时端口号:客户端程序使用临时端口号,它是运行在客户端上的 TCP/IP 软件随机选取的,范围为 49152-65535。
我们平时进行网络编程时服务器最好使用注册端口号,而客户端的端口号则是系统随机分配的,即临时端口号。
#### UDP 用户数据报协议
UDP 协议主要有以下一些特点:
- 无连接的:发送数据之前不需要建立连接,因此减少了开销和发送数据之前的时延。
- 尽最大努力交付:即不保证可靠交付,因此主机不需要维持复杂的连接状态表。
- 面向报文的UDP 对应用层传递下来的报文既不合并也不拆分而是保留这些报文的边界。UDP 对于应用程序提交的报文,添加头部后就向下提交给网络层。
- 没有拥塞控制网络出现的拥塞时UDP 不会使源主机的发送速率降低。这对某些实时应用是很重要的,很适合多媒体通信的要求。
- 支持多对多的交互通信
UDP 的适用场景:
- 适用于少量(几百个字节)的数据。
- 对性能的要求高于对数据完整性的要求如视频播放、P2P、DNS 等。
- 需要“简短快捷”的数据交换 简单的请求与应答报文交互,如在线游戏。
- 需要多播和广播的应用,源主机以恒定速率发送报文,拥塞发生时允许丢弃部分报文,如本地广播、隧道 VPN。
#### TCP 传输控制协议
TCP 协议有以下特点:
- 面向连接的传输服务。打电话式、会话式通信。
- 面向字节流传输服务(而 UDP 是面向报文)。字节管道、字节按序传输和到达。
- 全双工通信。一个应用进程可以同时接收和发送数据、捎带确认;通信双方都设置有发送和接收缓冲区,应用程序将要发送的数据字节提交给发送缓冲区,实际发送由 TCP 协议控制,接收方收到数据字节后将它存放在接收缓冲区,等待高层应用程序读取。
- 可建立多个并发的 TCP 连接。如 Web 服务器可同时与多个客户端建立的连接会话。
- 可靠传输服务。不丢失数据、保持数据有序、向上层不重复提交数据(通过确认机制、拥塞控制等方式实现), 想象一下 ATM 机转帐应用就需要上述可靠性。
TCP 的报头如下图所示。
![图片描述](https://typoraflykhan.oss-cn-beijing.aliyuncs.com/202303311423424.jpeg)
重点关注几个标志位的意义,如下:
![图片描述](https://typoraflykhan.oss-cn-beijing.aliyuncs.com/202303311423436.jpeg)
TCP 连接包括连接建立、报文传输、连接释放三个阶段,其中连接建立的三次握手过程较为重要。
建立连接的三次握手过程:
1当客户端准备发起一次 TCP 连接首先向服务器发送第一个“SYN”报文控制位 SYN=1
2服务器收到 SYN 报文后如果同意建立连接则向客户端发送第二个“SYN+ACK”报文控制位 SYN=1ACK=1该报文表示对第一个 SYN 报文请求的确认。
3接收到 SYN+ACK 报文后,客户端发送第三个 ACK 报文,表示对 SYN+ACK 报文的确认。
![图片描述](https://typoraflykhan.oss-cn-beijing.aliyuncs.com/202303311423331.jpeg)
### 用 C++ 进行 TCP 套接字网络编程
网络编程中我们一般会使用 C/S 架构,即包含服务器端和客户端。
#### TCP 网络编程的服务器端
服务器端一般先用 socket 创建一个套接字,然后用 bind 给这个套接字绑定地址(即 ip+端口号),然后调用 listen 把这个套接字置为监听状态,随后调用 accept 函数从已完成连接队列中取出成功建立连接的套接字,以后就在这个新的套接字上调用 send、recv 来发送数据、接收数据,最后调用 close 来断开连接释放资源即可。
过程如下:
![图片描述](https://typoraflykhan.oss-cn-beijing.aliyuncs.com/202303311435369.jpeg)
#### TCP 网络编程的客户端
与服务器不同,客户端并不需要 bind 绑定地址,因为端口号是系统自动分配的,而且客户端也不需要设置监听的套接字,因此也不需要 listen。客户端在用 socket 创建套接字后直接调用 connect 向服务器发起连接即可connect 函数通知 Linux 内核完成 TCP 三次握手连接,最后把连接的结果作为返回值。成功建立连接后我们就可以调用 send 和 recv 来发送数据、接收数据,最后调用 close 来断开连接释放资源。
过程如下:
![图片描述](https://typoraflykhan.oss-cn-beijing.aliyuncs.com/202303311435425.jpeg)
#### 完整流程
TCP 网络编程的整体流程如下图所示:
![图片描述](https://typoraflykhan.oss-cn-beijing.aliyuncs.com/202303311435452.jpeg)
#### TCP 网络编程的相关数据结构
套接字地址结构:
```cpp
struct sockaddr_in {
short int sin_family; /* 地址族 */
unsigned short int sin_port; /* 端口号 */
struct in_addr sin_addr; /* ip地址 */
unsigned char sin_zero[8];
};
```
上述结构体涉及到的另一个结构体 in_addr 如下:
```cpp
struct in_addr {
unsigned long s_addr;
};
```
#### TCP 网络编程各函数的定义
socket 函数:
```cpp
int socket( int domain, int type,int protocol)
/*
功能:创建一个新的套接字,返回套接字描述符
参数说明:
domain域类型指明使用的协议栈如TCP/IP使用的是PF_INET其他还有AF_INET6、AF_UNIX
type:指明需要的服务类型, 如
SOCK_DGRAM:数据报服务UDP协议
SOCK_STREAM:流服务TCP协议
protocol:一般都取0(由系统根据服务类型选择默认的协议)
*/
```
bind 函数:
```cpp
int bind(int sockfd,struct sockaddr* my_addr,int addrlen)
/*
功能:为套接字绑定地址
TCP/IP协议使用sockaddr_in结构包含IP地址和端口号服务器使用它来指明熟知的端口号然后等待连接
参数说明:
sockfd:套接字描述符,指明创建连接的套接字
my_addr:本地地址IP地址和端口号
addrlen:地址长度
*/
```
listen 函数:
```cpp
int listen(int sockfd,int backlog)
/*
功能:
将一个套接字置为监听模式,准备接收传入连接。用于服务器,指明某个套接字连接是被动的监听状态。
参数说明:
Sockfd:套接字描述符,指明创建连接的套接字
backlog: linux内核2.2之前backlog参数=半连接队列长度+已连接队列长度linux内核2.2之后backlog参数=已连接队列Accept队列长度
*/
```
accept 函数:
```cpp
int accept(int sockfd, struct sockaddr *addr, int *addrlen)
/*
功能:从已完成连接队列中取出成功建立连接的套接字,返回成功连接的套接字描述符。
参数说明:
Sockfd:套接字描述符,指明正在监听的套接字
addr:提出连接请求的主机地址
addrlen:地址长度
*/
```
send 函数:
```cpp
int send(int sockfd, const void * data, int data_len, unsigned int flags)
/*
功能在TCP连接上发送数据,返回成功传送数据的长度出错时返回1。send会将数据移到发送缓冲区中。
参数说明:
sockfd:套接字描述符
data:指向要发送数据的指针
data_len:数据长度
flags:通常为0
*/
```
recv 函数:
```cpp
int recv(int sockfd, void *buf, intbuf_len,unsigned int flags)
/*
功能:接收数据,返回实际接收的数据长度出错时返回1。
参数说明:
Sockfd:套接字描述符
Buf:指向内存块的指针
Buf_len:内存块大小,以字节为单位
flags:一般为0
*/
```
close 函数:
```cpp
close(int sockfd)
/*
功能:撤销套接字。如果只有一个进程使用,立即终止连接并撤销该套接字,如果多个进程共享该套接字,将引用数减一,如果引用数降到零,则关闭连接并撤销套接字。
参数说明:
sockfd:套接字描述符
*/
```
connect 函数:
```cpp
int connect(int sockfd,structsockaddr *server_addr,int sockaddr_len)
/*
功能: 同远程服务器建立主动连接成功时返回0若连接失败返回1。
参数说明:
Sockfd:套接字描述符,指明创建连接的套接字
Server_addr:指明远程端点IP地址和端口号
sockaddr_len :地址长度
*/
```