C++網絡編程離不開socket編程。咱們如今使用socket編寫簡單的回聲服務器。c++
這裏所說的流程包括兩部分:git
回聲服務器主要功能:服務器將接收到來自客戶端的數據傳回客戶端。github
服務器的功能:編程
客戶端的功能:服務器
#include <cstdio> #include <cstdlib> #include <cstring> #include <unistd.h> #include <arpa/inet.h> #include <sys/socket.h> const int BUF_SIZE = 1024; void error_handling(const char *message); // 接收兩個參數,argv[1]爲端口號 int main(int argc, char *argv[]) { int server_socket; int client_sock; char message[BUF_SIZE]; ssize_t str_len; int i; struct sockaddr_in server_addr; struct sockaddr_in client_addr; socklen_t client_addr_size; if (argc != 2) { printf("Usage: %s <port>\n", argv[0]); exit(1); } server_socket = socket(PF_INET, SOCK_STREAM, 0); // 建立IPv4 TCP socket if (server_socket == -1) { error_handling("socket() error"); } // 地址信息初始化 memset(&server_addr, 0, sizeof(server_addr)); server_addr.sin_family = AF_INET; // IPV4 地址族 server_addr.sin_addr.s_addr = htonl(INADDR_ANY); // 使用INADDR_ANY分配服務器的IP地址 server_addr.sin_port = htons(atoi(argv[1])); // 端口號由第一個參數設置 // 分配地址信息 if (bind(server_socket, (struct sockaddr*)&server_addr, sizeof(sockaddr)) == -1) { error_handling("bind() error"); } // 監聽鏈接請求,最大同時鏈接數爲5 if (listen(server_socket, 5) == -1) { error_handling("listen() error"); } client_addr_size = sizeof(client_addr); for (i = 0; i < 5; ++i) { // 受理客戶端鏈接請求 client_sock = accept(server_socket, (struct sockaddr*)&client_addr, &client_addr_size); if (client_sock == -1) { error_handling("accept() error"); } else { printf("Connect client %d\n", i + 1); } // 讀取來自客戶端的數據 while ((str_len = read(client_sock, message, BUF_SIZE)) != 0) { // 向客戶端傳輸數據 write(client_sock, message, (size_t)str_len); message[str_len] = '\0'; printf("client %d: message %s", i + 1, message); } } // 關閉鏈接 close(client_sock); printf("echo server\n"); return 0; }
#include <cstdio> #include <cstdlib> #include <cstring> #include <unistd.h> #include <arpa/inet.h> #include <sys/socket.h> const int BUF_SIZE = 1024; void error_handling(const char *message); // 接收兩個參數,argv[1]爲IP地址,argv[2]爲端口號 int main(int argc, char *argv[]) { int sock; struct sockaddr_in server_addr; char message[BUF_SIZE]; ssize_t str_len; if (argc != 3) { printf("Usage : %s <IP> <port>\n", argv[0]); exit(1); } sock = socket(PF_INET, SOCK_STREAM, 0); if (sock == -1) { error_handling("socket() error"); } // 地址信息初始化 memset(&server_addr, 0, sizeof(server_addr)); server_addr.sin_family = AF_INET; // IPV4 地址族 server_addr.sin_addr.s_addr = inet_addr(argv[1]); // 服務器IP地址 server_addr.sin_port = htons(atoi(argv[2])); // 服務器端口號 // 向服務器發送鏈接請求 if (connect(sock, (struct sockaddr*)&server_addr, sizeof(server_addr)) == -1) { error_handling("connect() error"); } else { printf("Connect..."); } while (1) { printf("Input message( Q to quit ): "); fgets(message, BUF_SIZE, stdin); // 若是輸入q或者Q,則退出 if (!strcmp(message, "q\n") || !strcmp(message, "Q\n")) { break; } write(sock, message, strlen(message)); // 向服務器發送數據 str_len = read(sock, message, BUF_SIZE); // 讀取來自客戶端的服務器 message[str_len] = 0; printf("Message from server: %s \n", message); } // 關閉鏈接 close(sock); return 0; }
客戶端傳輸數據,經過調用write函數一次性發送,以後調用一次read函數,指望接收本身傳輸的數據。只是問題所在。由於「TCP不存在數據邊界」,存在兩個異常狀況:網絡
github併發
《TCP/IP網絡編程》socket