TCP/IP 网络编程 (抄书笔记 2) – UDP
来源: 《TCP/IP 网络编程》
抄书:
TCP 协议若要向 10 个客户端提供服务, 除了需要 listen 套接字外, 还需要 10 个服务器端套接字
(accept), 但是在 UDP 中, 不管是服务器端还是客户端都只需要 1 个套接字
udp 的 client 不需要 bind, 调用 sendto 函数的时候如果发现没有地址会自动分配相应的套接字,
分配的地址保留直到程序结束
UDP 的客户端可以使用 connect(sock, message, sizeof(message)), 好处
- 不用为每个 UDP 连接新建一个套接字
- 还可以使用 read, write 函数, 不需要使用 sendto, recvfrom
server
int server_sock; struct sockaddr_in server_addr; struct sockaddr_in client_addr; socklen_t client_size; server_sock = socket(AF_INET, SOCK_DGRAM, 0); 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)); char buf[BUF_SIZE+1]; int str_len; while (1) { client_size = sizeof(client_addr); str_len = recvfrom(server_sock, buf, BUF_SIZE, 0, (struct sockaddr *)&client_addr, &client_size); if (str_len == 0) { break; } sendto(server_sock, buf, str_len, 0, (struct sockaddr *)&client_addr, client_size); } close(server_sock);
client
int server_sock; struct sockaddr_in server_addr; socklen_t server_size; server_sock = socket(AF_INET, SOCK_DGRAM, 0); memset(&server_addr, 0, sizeof(server_addr)); server_addr.sin_family = AF_INET; server_addr.sin_port = htons(atoi(argv[2])); inet_aton(argv[1], &server_addr.sin_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; } sendto(server_sock, buf, strlen(buf), 0, (struct sockaddr *)&server_addr, sizeof(server_addr)); server_size = sizeof(server_addr); str_len = recvfrom(server_sock, buf, BUF_SIZE, 0, (struct sockaddr *)&server_addr, &server_size); buf[str_len] = 0; printf("from server: %s\n", buf); } close(server_sock);
connect
int server_sock; struct sockaddr_in server_addr; socklen_t server_size; server_sock = socket(AF_INET, SOCK_DGRAM, 0); memset(&server_addr, 0, sizeof(server_addr)); server_addr.sin_family = AF_INET; server_addr.sin_port = htons(atoi(argv[2])); inet_aton(argv[1], &server_addr.sin_addr); +++ 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; } sendto(server_sock, buf, strlen(buf), 0, (struct sockaddr *)&server_addr, sizeof(server_addr)); server_size = sizeof(server_addr); str_len = recvfrom(server_sock, buf, BUF_SIZE, 0, (struct sockaddr *)&server_addr, &server_size); buf[str_len] = 0; printf("from server: %s\n", buf); } close(server_sock);