先來一張經典的流程圖
接下介紹一下大概流程,各個函數的參數大家自己去了解加深一下印象
服務端流程
?1.創建套接字:使用?socket
?函數創建一個套接字,這個套接字后續會被用于監聽客戶端的連接請求。? ?需要注意的是,服務端一般有倆個描述符,一個用于連接和監聽,一個用于通信,這里用socket
?函數創建的套接字就是用于和客戶端建立連接和監聽客戶端的連接請求的
例如在?C 語言中:
#include <sys/socket.h>
#include <netinet/in.h>
#include <stdio.h>
#include <unistd.h>int main() {int listenSocket = socket(AF_INET, SOCK_STREAM, 0);if (listenSocket == -1) {perror("socket creation failed");return -1;}// 后續操作return 0;
}
2.綁定地址和端口:使用?bind
?函數將創建的套接字與指定的 IP 地址和端口進行綁定,向操作系統表明服務端要監聽該地址和端口上的連接請求。示例如下:
struct sockaddr_in serverAddr;
serverAddr.sin_family = AF_INET;
serverAddr.sin_addr.s_addr = INADDR_ANY; // 監聽所有可用網絡接口
serverAddr.sin_port = htons(8888); // 綁定到 8888 端口if (bind(listenSocket, (struct sockaddr *)&serverAddr, sizeof(serverAddr)) == -1) {perror("bind failed");close(listenSocket);return -1;
}
為什么bind綁定時一定要將套接字和服務器的ip和端口綁定在一起呢?我的理解是客戶端相當于一個想入住酒店的旅客,套接字就相當于房卡,有了這張房卡旅客才能知道樓層和具體房間在哪里。
3.監聽連接請求:使用?listen
?函數將套接字設置為監聽狀態,指定最大允許的連接請求隊列長度。
示例如下:
if (listen(listenSocket, 5) == -1) {perror("listen failed");close(listenSocket);return -1;
}
4.接受連接并創建新套接字:使用?accept
?函數接受客戶端的連接請求。當有客戶端發起連接時,accept
?函數會阻塞直到有連接到來,然后返回一個新的套接字用于與該客戶端進行數據通信,同時獲取客戶端的地址信息(包括 IP 地址和端口號)。示例如下:
struct sockaddr_in clientAddr;
socklen_t clientAddrLen = sizeof(clientAddr);
int clientSocket = accept(listenSocket, (struct sockaddr *)&clientAddr, &clientAddrLen);
if (clientSocket == -1) {perror("accept failed");close(listenSocket);return -1;
}
客戶端流程
1.創建套接字:同樣使用?socket
?函數創建一個套接字,用于與服務端建立連接和進行數據通信。示例如下:
int clientSocket = socket(AF_INET, SOCK_STREAM, 0);
if (clientSocket == -1) {perror("socket creation failed");return -1;
}
2.發起連接請求:使用?connect
?函數向服務端發起連接請求,在?connect
?函數中指定服務端的 IP 地址和端口號。示例如下:
struct sockaddr_in serverAddr;
serverAddr.sin_family = AF_INET;
serverAddr.sin_addr.s_addr = inet_addr("127.0.0.1"); // 服務端 IP 地址
serverAddr.sin_port = htons(8888); // 服務端端口if (connect(clientSocket, (struct sockaddr *)&serverAddr, sizeof(serverAddr)) == -1) {perror("connect failed");close(clientSocket);return -1;
}
3.數據通信:連接建立后,客戶端通過自己創建的套接字?clientSocket
?與服務端?accept
?返回的用于通信的新套接字進行數據交互,使用?send
?函數發送數據,使用?recv
?函數接收數據。