TCPTP协议是什么?以及Socket使用指南

TCP/TP协议是什么?

TCP/IP协议是一种四层协议,完整叫法是TCP/UDP/IP协议。

UDP 协议 (User Datagram Protocol 用户数据报协议),是一种保护消息边界的,不保障可靠数据的传输。

TCP 协议 (Transmission Control Protocol 传输控制协议),是一种流传输,无保护信息边界的协议。他提供可靠的、有序的、双向的、面向连接的传输。

保护信息边界 :传输协议把数据当作 一条独立的信息 在网上传输,接收端只能接受独立的信息。

无保护信息边界 :发送端连续发送数据,接收端可能在一次接受动作中,接受多个数据包。

Socket

介绍(与TCP/TP的关系)

Windows Socket是一个网络编程接口,它并非一个协议,而是一些协议的封装。

WinSock与协议基本上无关,这样可以保证其独立性,能够调用多种不同协议的功能。

WinSock可以是TCP/IP协议的一种封装,通过调用WinSock的接口函数来调用TCP/IP的各种功能。

基本使用流程

WinSock编程分为服务器端和客户端两部分。

接下来直接以TCP/IP为例来介绍其基本使用流程。

1.初始化

初始化WinSock DLL库:

cpp 复制代码
#include <winsock2.h>
#pragma comment(lib,"ws2_32.lib") 			    //告诉链接器链接 WinSock 库
	
WSADATA wsaData;							  //保存 WinSock 版本
int ret = WSAStarup(MAKEWORD(2,2),&wsaData);	//申请网络资源,指定使用版本
if(ret != 0){
	printf("初始化失败")
}

如果不调用WSAStartup,后面所有socket API都会失败。

2.创建Socket

基本格式:

cpp 复制代码
SOCKET serverSocket = socket(
	AD_INTE,		// 使用IPv4协议
	SOCK_STREAM,	// 面向连接(TCP)
	IPPROTO_TCP		// 说明使用 TCP 协议
);

if(serverSocket == INVALID_SOCKET){
	printf("创建失败");
}
3.设置通信地址(IP 与 端口)

基本格式:

SOCKET Socket(int af,int type,int protocol)

包含了两个信息,一个是 IP 地址,一个是 Port 端口号,使用这两个信息,就可以确定网络中的任何一个通讯节点。

cpp 复制代码
sockaddr_in addr{};			    // 这个是IPv4专用地址结构体,内部包含 IP 与 端口
addr.sin_family = AD_INET;		// 知名地址类型是 IPv4
addr.sin_port = htons(8080);	// 设置端口
addr.sin_addr.s_addr = INADDR_ANY;
4.绑定端口(服务端)

当调用Socket()接口函数创建了一个套接字之后,必须把套接字与你需要进行通讯的地址建立联系,使用bind函数来进行绑定。

cpp 复制代码
bind(sock, (sockaddr*)&addr, sizeof(addr));

绑定端口的作用就是告诉操作系统,此端口我占用了,其他端不能抢占我的位置。

如果不进行绑定的话,服务端会不知道监听那个端口,而客户端也无法进行监听。

5.监听(服务端)

当绑定完成之后,服务端必须建立一个监听队列来接受客户端的连接请求。

cpp 复制代码
int listen(SOCKET s,int backlog)

将socket从普通的状体转化为监听的状态。

这里的参数backlog指的是允许的最大连接队列长度。

6.建立连接

在服务端,使用accept

cpp 复制代码
SOCKET clientSock = accept(sock, nullptr, nullptr);

从而从连接队列中取出一个已完成三次握手的客户端。

在客户端,使用connect

cpp 复制代码
connect(sock,(sockaddr*)&serverAddr,sizeof(serverAddr));

从而主动向服务器发起 TCP 三次握手。

此时,TCP已经完成连接建立,可以收发数据

7.数据收发

此时,在客户端与服务端建立连接以后,这两端都可以进行数据的发送与接收,使用以下方法:

发送:

cpp 复制代码
int send(SOCKET s,const char FAR* buf,int len,int flags);

接收:

cpp 复制代码
int recv(SOCKET s,char FAR* buf,int len,int flags);

注意buf这个参数,注意这是将数据存入 TCP 缓冲区,实际是否进行发送或接收由 TCP 决定。

注意flag这个参数,当其值 >0 时,表示接收到数据;当其值 = 0 时,表示对方正常关闭;当其值 < 0 时,表示出现了错误。

8.关闭Socket

当所有收发操作完成之后,我们要关闭Socket,告知对方:我不再通信,从而释放系统资源,防止句柄泄漏。

cpp 复制代码
closesocket(sock);
9.清理环境

归还 WinSock 初始化时申请的资源,避免资源泄漏与程序异常退出。

cpp 复制代码
WSACleanuo();

总结一下,Socket的基本使用流程如下:

md 复制代码
1. WSAStartup      // 初始化 WinSock
2. socket          // 创建 socket
3. bind            // 绑定地址(服务端)
4. listen          // 监听(服务端)
5. accept / connect// 建立连接
6. send / recv     // 数据通信
7. closesocket     // 关闭 socket
8. WSACleanup      // 清理 WinSock

Socket的通信模式

1. 阻塞模式(默认)
  • accept / recv卡住线程
  • 适合教学、小工具
  • 不适合高并发

2. 非阻塞模式
cpp 复制代码
u_long mode = 1;
ioctlsocket(sock, FIONBIO, &mode);
  • 需要轮询
  • CPU 消耗较高

3. 事件驱动(WSAEventSelect)
  • 基于事件通知
  • 中等规模服务器

4. IOCP(工业级)

Windows 高性能服务器核心技术

  • Completion Port
  • 异步 + 线程池
  • 支撑高并发(如 Web Server、游戏服务器)
  • Windows 下高并发服务,基本绕不开 IOCP。

WinSock 与 Linux Socket 的对比

对比点 Windows Linux
初始化 必须 WSAStartup 不需要
关闭 closesocket close
错误码 WSAGetLastError() errno
高并发 IOCP epoll
头文件 winsock2.h sys/socket.h
相关推荐
咔咔咔的2 小时前
840. 矩阵中的幻方
c++
阿拉伯柠檬2 小时前
传输层协议TCP(一)
linux·网络·网络协议·tcp/ip·面试
学习者0072 小时前
NE相关知识之------OSPF
网络
星火开发设计2 小时前
栈的深度解析与C++实现
开发语言·数据结构·c++·学习·知识
再睡一夏就好2 小时前
LInux线程池实战:单例模式设计与多线程安全解析
linux·运维·服务器·开发语言·javascript·c++·ecmascript
yenggd2 小时前
openEuler24.3源码包安装zabbix6.2
服务器·网络·zabbix
我家大宝最可爱2 小时前
windows搭建agent环境
c++·chatgpt
写代码的橘子n2 小时前
RIPng报文的格式、路由表条目结构以及报文处理流程
计算机网络·ripng
zfj3212 小时前
Linux第一个用户空间进程init进程的演进过程
linux·运维·网络