TCP协议服务端与客户端

本文详细介绍了TCP/IP协议的基础知识,包括协议簇中的应用层、网络层和网络访问层的主要协议。重点讲解了TCP与UDP的区别,以及TCP的三次握手和四次挥手过程。接着,通过实例展示了TCP服务器的创建、绑定、监听、接收连接和数据传输步骤,并给出了TCP客户端如何连接服务器和发送数据的代码示例。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一、TCP/IP协议简介

什么是TCP/IP

TCP/IP协议是一种用于因特网的通信协议。TCP指传输控制协议(Transmission Control Protocol),IP指网际协议(Internet Protocol)。

TCP/IP协议簇中的协议

TCP/IP协议是一个协议簇,其中包含许多协议,囊括了应用层、传输层、网络层以及网络访问层。

  • 应用层包括:
    ①超文本传输协议(HTTP),万维网的基本协议
    ②TFTP文件传输协议
    ③Telnet远程登录协议
    ④SNMP网络管理协议
    ⑤DNS域名解析
  • 网络层包括:
    ①网际(IP)协议
    ②因特网消息控制协议ICMP
    ③ARP地址解析协议
    ④RARP反向地址解析协议
  • 网络访问层:
    网络访问层是TCP/IP协议簇的最底层,它提供物理网络的接口,实现对复杂数据的发送和接收。网络访问层协议为网络接口、数据传输提供了对应的技术规范。TCP/IP中的网络访问层对应OSI七层网络模型中的物理层和数据链路层。
    OSI七层网络模型

TCP、UDP的区别

TCP、UDP都是TCP/IP协议簇中的通信协议,其中TCP(Transmission Control Protocol)是面向连接的协议,而UDP(User Data Protocol)则是一个非连接的协议。

二、TCP协议应用

TCP的三次握手

TCP协议在进行数据通信之前必须建立连接,而TCP建立连接采用“三次握手”的方式。
TCP的三次握手
三次握手的过程就像打电话,如下:
小刘打电话给王哥,这个打电话的动作即发起连接请求(第一次握手),王哥听到来电铃声接起电话并说:“喂,小刘啊,听得到吗?”,这一步骤就如上图服务端响应客户端的连接请求(第二次握手),这时小刘听见电话里传来王哥的声音,知道王哥已经响应,便说道:“王哥,可以听到。”,这一步即上图中客户端对服务端的第三次握手,此时连接便已成功建立,小刘(客户端)和王哥(服务端)就可以进行通信了。

TCP的四次挥手

四次挥手
如同三次挥手像打电话一样,四次挥手也可以像挂断电话一般。如下:
小刘(客户端):王哥,事情大概就是这个样子。
王哥(服务端):好,这个事情你放心,没问题。
王哥(服务端):小刘,没啥事的话我就挂了啊。
小刘(客户端):好嘞,再见王哥。
此时连接断开。
拨打/挂断电话跟TCP的三次握手/四次挥手过程不完全一致,但可以用这个过程去初步理解,初步理解后再根据其原理进行深入理解。

TCP服务器

TCP服务器建立的流程是创建套接字、绑定套接字、监听套接字,然后进行收发消息、处理消息的操作。

1、创建套接字

函数原型,TCP协议的通信依靠套接字,在使用套接字之前,需要先使用socket()函数创建套接字,使用该函数时需要传入地址族(af)、数据传输方式/套接字类型(type)、传输协议三个参数(protocol)。
af为地址族(Address Family),即IP地址类型,常用的有AF_INET和AF_INET6。AF是"Address Family"的简写,INET是"Internet"的简写。AF_INET表示的是IPV4地址,AF_INET6则表示的是IPV6地址。(也可以使用PF(Protocol Family)前缀,与AF一致)
type为数据传输方式/套接字类型,常用的有SOCK_STREAM(数据流式套接字/面向连接的套接字)和SOCK_DGRAM(数据报式套接字/无连接的套接字)。
protocol为传输协议,常用的有IPPROTO_TCP和IPPROTO_UDP,分别表示TCP传输协议和UDP传输协议。在使用TCP或UDP协议时,由于SOCK_STREAM和SOCK_DGRAM分别只能用于TCP、UDP,因此该参数可以填0,系统会自行适配传输协议。

int socket(int af, int type, int protocol);
INT sockfd = 0;
sockfd = socket(AF_INET, SOCK_STREAM, 0);
if(0 > sockfd)
{
   
   
    SaveLog(MODULE_TCPSERVER, "ERROR:Create socket fail\r\n");
    return -1;
}

2、绑定、监听套接字

函数原型,sock为socket文件描述符,addr为sockaddr结构体变量的指针,addrlen为addr变量的大小。

int bind(int sock, struct sockaddr *addr, socklen_t addrlen);
struct sockaddr_in ServerAddr = {
   
   0};
memset(&ServerAddr, 0, sizeof(ServerAddr));
ServerAddr.sin_family = AF_INET;
ServerAddr.sin_port = htons(SERVER_PORT);
ServerAddr.sin_addr.s_addr = inet_addr("0.0.0.0");
if(0 > bind(sockfd, (struct sockaddr*)&ServerAddr,sizeof(ServerAddr)))
{
   
   
    SaveLog(MODULE_TCPSERVER, "ERROR:Bind failed\r\n");
    return -1;
}

函数原型,sock为socket文件描述符,backlog为请求队列的最大长度。

int listen(int sock, int backlog);
if(0 < listen(sockfd, SERVER_MAX_CON))
{
   
   
    SaveLog(MODULE_TCPSERVER, "ERROR:Listen failed\r\n");
    return -1;
}
return sockfd;

3、接收连接

TCP服务器完成套接字的创建、绑定与监听操作后,需要调用accept函数接收客户端的连接,函数原型为:

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

accpet()函数的参数与listen()函数的一致,不过返回值为客户端的socket描述符。

INT connfd = 0;
connfd = accept(sockfd, NULL, NULL);
if(0 > connfd)
{
   
   
    SaveLog(MODULE_TCPSERVER, "ERROR:accept failed\r\n");
}

4、数据传输

连接建立后,即可进行数据的传输。主要使用recv()函数和send()函数。函数原型如下:

int send(SOCKET sock, const char *buf, int len, int flags);
int recv(SOCKET sock, char *buf, int len,int flags);

其中,sock为套接字,buf为要发送或者存储接收数据的缓冲区地址,len为发送/接收的数据的字节数,flags为发送/接收数据的选项(一般为0或者NULL即可)。recv()函数和send()函数的返回值都为接收/发送的实际字节数。

struct sockaddr ClientAddr = {
   
   0};
struct sockaddr_in ClientAddrIn = {
   
   0};
INT iRes = 0;
ULONG ulNameLen = 0;
CHAR *szBuf[1024] = {
   
   0};

memset(&ClientAddr, 0, sizeof(ClientAddr));
memset(&ClientAddrIn, 0, sizeof(ClientAddrIn));
ulNameLen = sizeof(struct sockaddr);
connfd = (INT *)void_sockfd;

if(0 == getsockname(connfd, &ClientAddr, (socklen_t *)&ulNameLen))
{
   
   
    memcpy(&ClientAddrIn, &ClientAddr, ulNameLen)
### 回答1: 1. 打开终端,输入以下命令安装fcitx输入法: sudo apt-get install fcitx fcitx-config-gtk fcitx-table-wubi 2. 安装完毕后,打开“系统设置”-“语言支持”,将“键盘输入法系统”设置为fcitx。 3. 重新启动电脑,打开任意文本编辑器,按下Ctrl+Space键即可切换输入法,选择中文输入法即可开始输入中文。 ### 回答2: 在Linux系统下安装中文输入法有多种方法,以下是其中一种较常见的方法: 1. 打开终端,输入以下命令安装fcitx输入法框架: sudo apt-get install fcitx 2. 安装后,再次在终端中输入以下命令安装fcitx的输入法引擎: sudo apt-get install fcitx-googlepinyin 3. 安装完成后,打开系统设置,找到“地区语言”或“语言支持”选项,在“输入源”或“键盘输入法系统”中选择fcitx作为默认输入法。 4. 重新启动电脑,启动时会自动加载fcitx输入法框架。 5. 在系统托盘中找到输入法图标,右键点击选择“配置”,进入fcitx配置页面。 6. 在配置页面中,点击“+”号添加中文输入法。一般情况下,选择“pinyin”或“googlepinyin”作为中文输入法。 7. 完成上述步骤后,就可以在需要输入中文的应用程序中使用中文输入法了。在输入框中点击右键,选择“切换输入法”,或使用快捷键(默认为Ctrl + Space)进行切换。 需要注意的是,以上方法适用于大多数Linux系统,对于不同的发行版可能会有细微的差异。对于某些特定的发行版,也可以通过软件包管理器直接搜索安装相应的中文输入法。另外,还可以通过其他输入法框架,如ibus,来安装使用中文输入法。 ### 回答3: 要在Linux系统中安装中文输入法,可以按照以下步骤进行操作。 第一步,打开终端窗口,在终端中输入以下命令,以安装ibus输入法框架: sudo apt-get install ibus 第二步,再次在终端中输入以下命令,以安装ibus-pinyin中文输入法: sudo apt-get install ibus-pinyin 第三步,在终端中输入以下命令,以重新启动ibus服务: ibus restart 第四步,打开系统设置,选择“区域语言”或类似选项,找到“输入源”或“输入法”,然后添加中文输入法。 第五步,在输入法选项中选择新添加的中文输入法,这样就完成了中文输入法的安装。 在使用中文输入法时,可以通过以下方法进行切换: 方法一,使用快捷键:按下Ctrl+空格键,切换输入法。 方法二,通过任务栏中的输入法图标:点击输入法图标,然后从弹出的菜单中选择所需的输入法。 安装中文输入法后,可以在几乎所有的应用程序中使用中文输入。通过切换输入法,可以方便地在中文其他语言之间切换,满足自己的需求。
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值