一、 Socket 概述
Socket 是一種用於在不同進程間進行網絡通信的機制,也是 Linux 下網絡編程的基礎,也就是說在 Linux 下進行網絡通信主要就是使用 Socket。
其中 Socket 可以描述成是文件描述符,它是一個整數,就像文件描述符一樣可以使用 read、write、close 等函數對它進行操作。Socket 可以分為兩種類型:流式 Socket 和數據報式 Socket。
二、網絡編程基礎 API
下面先列舉一些 Network編程基礎 API:
//創建 Socket int socket(int domain, int type, int protocol); //命名 Socket int bind(int sockfd, const struct sockaddr *addr, socklen_t addrlen); //將未連接的 Socket 轉換為連接的 Socket int listen(int sockfd, int backlog); //向 Socket 發送數據 ssize_t send(int sockfd, const void *buf, size_t len, int flags); //從 Socket 接收數據 ssize_t recv(int sockfd, void *buf, size_t len, int flags); //建立連接請求的服務端 int accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen); //發起連接請求的客戶端 int connect(int sockfd, const struct sockaddr *addr, socklen_t addrlen); // 關閉 Socket int close(int sockfd);
三、流式 Socket
流式 Socket 是由 TCP 協議提供服務的,主要用於可靠的、有序的、基於連接的數據傳輸,特點如下:
1.面向連接;
2.提供可靠的數據傳輸;
3.通過三次握手連接,確保連接的建立;
4.數據是按順序傳輸的,不存在數據丟失、重複等問題。
3.1 服務端實現
// 創建 Socket int server_sockfd = socket(AF_INET, SOCK_STREAM, 0); // 命名 Socket struct sockaddr_in server_address; server_address.sin_family = AF_INET; // 地址族 server_address.sin_port = htons(12345); // 端口號 server_address.sin_addr.s_addr = htonl(INADDR_ANY); // IP 地址,INADDR_ANY 表示可以接收任何地址 bind(server_sockfd, (struct sockaddr *)&server_address, sizeof(server_address)); // 將未連接的 Socket 轉換為連接的 Socket listen(server_sockfd, 5); // 服務端等待客戶端的連接請求 int client_sockfd; struct sockaddr_in client_address; socklen_t client_len = sizeof(client_address); client_sockfd = accept(server_sockfd, (struct sockaddr *)&client_address, &client_len); // 向客戶端發送數據 char message[] = "Hello, client!"; write(client_sockfd, message, sizeof(message)); // 關閉 Socket close(client_sockfd); close(server_sockfd);
3.2 客戶端實現
// 創建 Socket int client_sockfd = socket(AF_INET, SOCK_STREAM, 0); // 向服務端發起連接請求 struct sockaddr_in server_address; server_address.sin_family = AF_INET; // 地址族 server_address.sin_port = htons(12345); // 端口號 server_address.sin_addr.s_addr = inet_addr("127.0.0.1"); connect(client_sockfd, (struct sockaddr*)&server_address, sizeof(server_address)); // 從服務端接收數據 char message[1024]; read(client_sockfd, message, sizeof(message)); printf("Message from server: %s\n", message); // 關閉 Socket close(client_sockfd);
四、數據報式 Socket
數據報式 Socket 是由 UDP 協議提供服務的,主要用於無連接、不可靠、允許數據失去和重複等問題的數據傳輸,特點如下:
1.無連接;
2.數據傳輸不可靠;
3.沒有三次握手連接,也無需維護連接狀態;
4.數據傳輸可能丟失、重複等問題。
4.1 服務端實現
// 創建 Socket int server_sockfd; server_sockfd = socket(AF_INET, SOCK_DGRAM, 0); // 命名 Socket struct sockaddr_in server_address; server_address.sin_family = AF_INET; // 地址族 server_address.sin_port = htons(12345); // 端口號 server_address.sin_addr.s_addr = htonl(INADDR_ANY); // IP 地址,INADDR_ANY 表示可以接收任何地址 bind(server_sockfd, (struct sockaddr*)&server_address, sizeof(server_address)); // 接收客戶端發送的數據 char message[1024]; struct sockaddr_in client_address; socklen_t client_len = sizeof(client_address); recvfrom(server_sockfd, message, sizeof(message), 0, (struct sockaddr*)&client_address, &client_len); printf("message from client: %s\n", message); // 向客戶端發送數據 char reply[] = "Hello, client!"; sendto(server_sockfd, reply, sizeof(reply), 0, (struct sockaddr *)&client_address, client_len); // 關閉 Socket close(server_sockfd);
4.2 客戶端實現
// 創建 Socket int client_sockfd = socket(AF_INET, SOCK_DGRAM, 0); // 向服務端發送數據 char message[] = "Hello, server!"; struct sockaddr_in server_address; server_address.sin_family = AF_INET; // 地址族 server_address.sin_port = htons(12345); // 端口號 server_address.sin_addr.s_addr = inet_addr("127.0.0.1"); sendto(client_sockfd, message, sizeof(message), 0, (struct sockaddr *)&server_address, sizeof(server_address)); // 接收服務端發送的數據 char reply[1024]; struct sockaddr_in reply_address; socklen_t reply_len = sizeof(reply_address); recvfrom(client_sockfd, reply, sizeof(reply), 0, (struct sockaddr *)&reply_address, &reply_len); printf("reply from server: %s\n", reply); // 關閉 Socket close(client_sockfd);
五、總結
Linux Socket 編程是進行網絡通信的基礎,對於理解網絡通信原理、網絡編程都非常重要。本文主要介紹了流式 Socket 和數據報式 Socket 的創建、命名、通信等基本操作,通過代碼示例的方式進行詳細闡述。
原創文章,作者:TCSYN,如若轉載,請註明出處:https://www.506064.com/zh-hk/n/333476.html