引言
C言語作為一種歷史長久且功能富強的編程言語,在網路編程範疇有著廣泛的利用。TCP連接是網路編程中弗成或缺的一部分,它確保了數據傳輸的堅固性跟次序性。本文將帶領讀者從C言語的角度入門TCP連接編程,並深刻懂得其中的核心技能。
TCP連接基本
1. TCP協定概述
TCP(傳輸把持協定)是一種面向連接的、堅固的、基於位元組流的傳輸層通信協定。它供給了一種機制,確保數據包按次序、無錯誤地從發送方傳輸到接收方。
2. TCP連接樹破過程
TCP連接的樹破過程平日稱為三次握手,它包含以下步調:
- 第一次握手:客戶端發送一個SYN報文到伺服器,並進入SYN_SENT狀況。
- 第二次握手:伺服器收到SYN報文後,發送一個SYN+ACK報文作為呼應,並進入SYN_RECEIVED狀況。
- 第三次握手:客戶端收到SYN+ACK報文後,發送一個ACK報文作為確認,並進入ESTABLISHED狀況。
C言語實現TCP連接
1. 包含頭文件
在C言語中停止TCP編程時,須要包含以下頭文件:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <unistd.h>
2. 創建套接字
利用socket()
函數創建一個套接字,指定通信域(如AF_INET表示IPv4)、套接字範例(如SOCK_STREAM表示TCP)跟協定範例(平日為0,表示默許協定)。
int sockfd = socket(AF_INET, SOCK_STREAM, 0);
3. 設置伺服器地點跟埠
創建一個struct sockaddr_in
構造體,並設置其中的成員變數,包含地點跟埠號。
struct sockaddr_in server_address;
server_address.sin_family = AF_INET;
server_address.sin_port = htons(8080);
server_address.sin_addr.s_addr = INADDR_ANY;
4. 綁定套接字
利用bind()
函數將套接字綁定到指定的地點跟埠上。
bind(sockfd, (struct sockaddr *)&server_address, sizeof(server_address));
5. 監聽連接
利用listen()
函數開端監聽連接懇求。
listen(sockfd, 5);
6. 接收連接
利用accept()
函數接收客戶端的連接懇求。
struct sockaddr_in client_address;
int client_socket = accept(sockfd, (struct sockaddr *)&client_address, sizeof(client_address));
7. 通信
利用send()
跟recv()
函數發送跟接收數據。
char buffer[1024];
int bytes_read = recv(client_socket, buffer, sizeof(buffer), 0);
if (bytes_read > 0) {
send(client_socket, buffer, bytes_read, 0);
}
8. 封閉連接
在通信結束後,利用close()
函數封閉套接字,開釋資本。
close(client_socket);
close(sockfd);
實例代碼
以下是一個簡單的C言語TCP伺服器端跟客戶端實例:
// 伺服器端代碼
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <unistd.h>
int main() {
int serverfd, newsocket;
struct sockaddr_in address;
int opt = 1;
int addrlen = sizeof(address);
// 創建socket文件描述符
if ((serverfd = socket(AF_INET, SOCK_STREAM, 0)) == 0) {
perror("socket failed");
exit(EXIT_FAILURE);
}
// 強迫綁定到埠8080
if (setsockopt(serverfd, SOL_SOCKET, SO_REUSEADDR | SO_REUSEPORT, &opt, sizeof(opt))) {
perror("setsockopt");
exit(EXIT_FAILURE);
}
address.sin_family = AF_INET;
address.sin_addr.s_addr = INADDR_ANY;
address.sin_port = htons(8080);
// 綁定socket到埠8080
if (bind(serverfd, (struct sockaddr *)&address, sizeof(address)) < 0) {
perror("bind failed");
exit(EXIT_FAILURE);
}
// 監聽連接懇求
if (listen(serverfd, 3) < 0) {
perror("listen");
exit(EXIT_FAILURE);
}
// 接收連接
newsocket = accept(serverfd, (struct sockaddr *)&address, (socklen_t*)&addrlen);
if (newsocket < 0) {
perror("accept");
exit(EXIT_FAILURE);
}
// 通信
char buffer[1024] = {0};
int valread = read(newsocket, buffer, 1024);
if (valread > 0) {
printf("%s\n", buffer);
}
// 封閉連接
close(newsocket);
close(serverfd);
return 0;
}
總結
經由過程本文的介紹,讀者應當對C言語TCP連接編程有了基本的懂得。控制TCP連接編程的核心技能對網路編程至關重要,盼望本文能幫助讀者在將來的網路編程現實中獲得更好的成果。