C++之TCP三次握手(笔记)
Posted 小懵白生活小趣谈
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了C++之TCP三次握手(笔记)相关的知识,希望对你有一定的参考价值。
socket套接字既不是运输层的协议,也不是应用层的协议,而是处于这两者之间的中间软件抽象层,它是一组接口。
1、对于理论知识上讲解:
TCP是面向连接的协议,其运输连接管理主要有三个阶段,即:连接建立、数据传送和连接释放。
其建立连接方式如下:
此时TCP报头的同步SYN、确认ACK标志位置1,表示允许建立连接,此时TCP报头的确认序列号为x+1,假设序列号为y;
理论已经出来了,那么接下来就代码实现了;
对于C++程序编写来说,服务端代码如下:
using namespace std;
bool initialization(SOCKET&conn);
int main(){
SOCKET conn;
char recvBuf[100];
if(initialization(conn)){
//填写接收客户端发送数据代码
while (1){
recv(conn, recvBuf, 100, 0);
};
return 0;
}
bool initialization(SOCKET&conn) {
WSADATA wsaData;
SOCKET sockServer;
SOCKADDR_IN addrServer;
SOCKADDR_IN addr;
if(WSAStartup(MAKEWORD(2, 2), &wsaData)!=0) //初始化套接子库
return false;
sockServer = socket(AF_INET, SOCK_STREAM, 0); //创建套接字
//准备通信地址
addrServer.sin_addr.S_un.S_addr = htonl(INADDR_ANY);
addrServer.sin_family = AF_INET;
addrServer.sin_port = htons(8090);
bind(sockServer, (SOCKADDR*)&addrServer, sizeof(SOCKADDR)); //IP、端口绑定
if(listen(sockServer, 5)<0){ //监听端口信息
WSACleanup();
retrun false;
}
conn = accept(sockServer, (SOCKADDR*)&addr, &len); ////监听客户端连接
return true;
}
客户端代码实现如下:
using namespace std;
bool Init_Client(SOCKET&Client);
int main()
{
SOCKET Client;
Client= socket(AF_INET, SOCK_STREAM, 0);
if(Init_Client(Client)){
while(1){
cin >> send_buf;
send_len = send(Client, send_buf, 100, 0);
//............
} }
}
bool Init_Client(SOCKET&Client) {
WORD w_req = MAKEWORD(2, 2);//版本号
WSADATA wsadata;
if (WSAStartup(w_req, &wsadata)!= 0) {
cout << "初始化套接字库失败!" << endl;
return false;
}
if (connect(Client, (SOCKADDR *)&server_addr, sizeof(SOCKADDR)) == SOCKET_ERROR) {
cout << "服务器连接失败!" << endl;
WSACleanup();
return false;
}
return true;
}
也就是说:首先服务器端先初始化Socket对象,然后与端口绑定(bind),对端口进行监听(listen),调用accept阻塞,等待客户端连接。
客户端通过调用accept函数,向服务端发送一个请求包,将TCP报头的同步SYN标志位置为1,表示希望建立连接,假设序列号为x;
服务端接收到客户端的数据包后,发送一个确认包给客户端。
将TCP报文的同步SYN标志位、确认ACK标志位置为1,确认序列号为x+1,表示允许建立连接,假设序列号为y;
客户端接收到服务端的相应包后,向服务端发送一个相应包,将TCP报头的确认ACK标志位置为1,确认序列号为y+1.序列号为x+1;
如此,两者双方可以进行数据通信了。
对于为什么不能两次握手:
这主要是为了防止已失效的连接请求报文段突然又传送到了服务端B。
此时服务端误认为客户端又发出一次新的连接请求,于是就向客户端发出确认报文段,同意建立连接。
但此时的客户端会忽略服务端发来的确认,也不发送数据,则服务端一致等待客户端发送数据,这样就浪费资源。
而所谓的失效的报文段:
是指当客户端发送一个连接请求报文,因久久未能接收到确认,然后重新发生一个连接请求报文。
后来收到了确认,建立了连接。数据传输完毕后,就释放了连接。
但是当第一个丢失的报文段只是在某些网络结点长时间滞留了,延误到连接释放以后的某个时间才到达服务端。
END
以上是关于C++之TCP三次握手(笔记)的主要内容,如果未能解决你的问题,请参考以下文章