TCP/IP 网络编程 (抄书笔记 1) – TCP
Table of Contents
来源: 《TCP/IP 网络编程》
抄书:
通信的双方都各自 拥有 输入缓存和输出缓存
socket 的 write 函数并不是立即传输数据, 而是写到输出缓存区, 到达另一端的输入缓存区
socket 的 read 函数调用的瞬间, 就从输入缓存区中读取数据
TCP 协议中的滑动窗口会保证 数据传输的时候不会超过输入缓存的大小
write(server_sock, message, strlen(message)); read(server_sock, message, strlen(message)); // 会有问题
server
int server_sock; int client_sock; struct sockaddr_in server_addr; struct sockaddr_in client_addr; // socket server_sock = socket(AF_INET, SOCK_STREAM, 0); // bind memset(&server_addr, 0, sizeof(server_addr)); server_addr.sin_family = AF_INET; server_addr.sin_addr.s_addr = htonl(INADDR_ANY); server_addr.sin_port = htons(atoi(argv[1])); bind(server_sock, (struct sockaddr *)&server_addr, sizeof(server_addr)); // listen listen(server_sock, 5); // accept socklen_t client_size = sizeof(client_addr); client_sock = accept(server_sock, (struct sockaddr *)&client_addr, &client_size); char buf[BUF_SIZE]; int str_len; while (1) { str_len = read(client_sock, buf, BUF_SIZE); if (str_len == 0) { break; } write(client_sock, buf, str_len); } close(server_sock); close(client_sock);
client
int server_sock; struct sockaddr_in server_addr; server_sock = socket(AF_INET, SOCK_STREAM, 0); memset(&server_addr, 0, sizeof(server_addr)); server_addr.sin_family = AF_INET; inet_aton(argv[1], &server_addr.sin_addr); server_addr.sin_port = htons(atoi(argv[2])); connect(server_sock, (struct sockaddr *)&server_addr, sizeof(server_addr)); char buf[BUF_SIZE+1]; int str_len; while (1) { printf("send to server (Q/q to quit): "); fgets(buf, BUF_SIZE, stdin); if (strcmp(buf, "Q\n") == 0 || strcmp(buf, "q\n") == 0) { break; } str_len = write(server_sock, buf, strlen(buf)); read(server_sock, buf, BUF_SIZE); buf[str_len] = 0; printf("from server: %s\n", buf); } close(server_sock);
更好的 client 端实现
int str_len; printf("send to server (Q/q to quit): "); fgets(buf, BUF_SIZE, stdin); if (strcmp(buf, "Q\n") == 0 || strcmp(buf, "q\n") == 0) { break; } str_len = write(server_sock, buf, strlen(buf)); --- read(server_sock, buf, BUF_SIZE); +++ int str_cnt = 0; +++ int str_read = 0; +++ while (str_cnt < str_len) { +++ str_read = read(server_sock, &buf[str_cnt], BUF_SIZE); +++ str_cnt += str_read; +++ } buf[str_len] = 0; printf("from server: %s\n", buf);