标签:puts 服务器 main 传递数据 code class tar win rcm
udp是具有数据边界的协议,传输中调用I/O函数的次数非常重要。输入函数的调用次数要和输出函数的调用次数完全一致,这样才能保证接受全部已发送的数据。
tcp套接字中需注册待传输数据的目标IP和端口,而udp中无需注册。通过sendto函数传递数据的过程大约分为3个阶段:
第1阶段:向udp套接字注册目标IP和端口号。
第2阶段:传输数据。
第3阶段:删除udp套接字中注册的目标地址信息。
每次调用sendto函数时都会重复上述过程。这种未注册目标地址信息的套接字成为未连接套接字,反之,注册了目标地址的套接字称为连接套接字。udp默认属于未连接套接字,创建已连接udp套接字只需调用connect函数,这样可以提高效率。
服务器端:
#include <stdio.h> #include <stdlib.h> #include <WinSock2.h> #define BUF_SIZE 64 void ErrorHandling(char* message); int main() { WSADATA wsa_data; SOCKET server_sock; SOCKADDR_IN server_addr, client_addr; int sz_client_addr; char message[BUF_SIZE]; int str_len; if (WSAStartup(MAKEWORD(2, 2), &wsa_data) != 0) ErrorHandling("WSAStartup() error."); server_sock = socket(PF_INET, SOCK_DGRAM, 0); if (server_sock == INVALID_SOCKET) ErrorHandling("socket() error."); 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(8000); if (bind(server_sock, (SOCKADDR*)&server_addr, sizeof(server_addr)) == SOCKET_ERROR) ErrorHandling("bind() error."); while (true) { sz_client_addr = sizeof(client_addr); str_len = recvfrom(server_sock, message, BUF_SIZE, 0, (SOCKADDR*)&client_addr, &sz_client_addr); sendto(server_sock, message, str_len, 0, (SOCKADDR*)&client_addr, sizeof(message)); } closesocket(server_sock); WSACleanup(); return 0; } void ErrorHandling(char* message) { fputs(message, stderr); fputc(‘\n‘, stderr); exit(1); }
使用连接套接字的客户端:
#include <stdio.h> #include <stdlib.h> #include <WinSock2.h> #define BUF_SIZE 64 void ErrorHandling(char* message); int main() { WSADATA wsa_data; SOCKET h_socket; SOCKADDR_IN server_addr; char message[BUF_SIZE]; int str_len; if (WSAStartup(MAKEWORD(2, 2), &wsa_data) != 0) ErrorHandling("WSAStartup() error."); h_socket = socket(PF_INET, SOCK_DGRAM, 0); if (h_socket == INVALID_SOCKET) ErrorHandling("socket() error."); memset(&server_addr, 0, sizeof(server_addr)); server_addr.sin_family = AF_INET; server_addr.sin_addr.s_addr = inet_addr("127.0.0.1"); server_addr.sin_port = htons(8000); if (connect(h_socket, (SOCKADDR*)&server_addr, sizeof(server_addr)) == SOCKET_ERROR) ErrorHandling("connect() error."); while (true) { fputs("Insert message(q to quit): ", stdout); fgets(message, sizeof(message), stdin); if (!strcmp(message, "q\n") || !strcmp(message, "Q\n")) break; send(h_socket, message, strlen(message), 0); str_len = recv(h_socket, message, sizeof(message) - 1, 0); message[str_len] = 0; printf("Message from server: %s", message); } closesocket(h_socket); WSACleanup(); return 0; } void ErrorHandling(char* message) { fputs(message, stderr); fputc(‘\n‘, stderr); exit(1); }
使用未连接套接字的客户端:
#include <stdio.h> #include <stdlib.h> #include <WinSock2.h> #define BUF_SIZE 64 void ErrorHandling(char* message); int main() { WSADATA wsa_data; SOCKET h_socket; SOCKADDR_IN server_addr, from_addr; char message[BUF_SIZE]; int str_len; if (WSAStartup(MAKEWORD(2, 2), &wsa_data) != 0) ErrorHandling("WSAStartup() error."); h_socket = socket(PF_INET, SOCK_DGRAM, 0); if (h_socket == INVALID_SOCKET) ErrorHandling("socket() error."); memset(&server_addr, 0, sizeof(server_addr)); server_addr.sin_family = AF_INET; server_addr.sin_addr.s_addr = inet_addr("127.0.0.1"); server_addr.sin_port = htons(8000); while (true) { fputs("Insert message(q to quit): ", stdout); fgets(message, sizeof(message), stdin); if (!strcmp(message, "q\n") || !strcmp(message, "Q\n")) break; sendto(h_socket, message, strlen(message), 0, (SOCKADDR*)&server_addr, sizeof(server_addr)); int sz_from_addr = sizeof(from_addr); str_len = recvfrom(h_socket, message, BUF_SIZE, 0, (SOCKADDR*)&from_addr, &sz_from_addr); message[str_len] = 0; printf("Message from server: %s", message); } closesocket(h_socket); WSACleanup(); return 0; } void ErrorHandling(char* message) { fputs(message, stderr); fputc(‘\n‘, stderr); exit(1); }
标签:puts 服务器 main 传递数据 code class tar win rcm
原文地址:https://www.cnblogs.com/ACGame/p/9908215.html