回声UDP服务器端/客户端

  UDP是具有数据边界的协议,传输中调用I/O函数的次数非常重要。输入函数的调用次数要和输出函数的调用次数完全一致,这样才能保证接受全部已发送的数据。

  TCP套接字中需注册待传输数据的目标IP和端口,而UDP中无需注册。通过sendto函数传递数据的过程大约分为3个阶段:
第1阶段:向udp套接字注册目标IP和端口号。
第2阶段:传输数据。
第3阶段:删除udp套接字中注册的目标地址信息。
  每次调用sendto函数时都会重复上述过程。这种未注册目标地址信息的套接字成为未连接套接字,反之,注册了目标地址的套接字称为连接connected套接字。UDP默认属于未连接套接字,创建已连接UDP套接字只需调用connect函数,这样可以提高效率。

1、linux

服务器端:

 1 #include <stdio.h>
 2 #include <stdlib.h>
 3 #include <string.h>
 4 #include <unistd.h>
 5 #include <arpa/inet.h>
 6 #include <sys/socket.h>
 7 
 8 #define BUF_SIZE 1024
 9 void error_handling(char * messages);
10 
11 int main(int argc, char *argv[])
12 {
13     if(argc != 2)
14     {
15         printf("Usage : %s <port>
", argv[0]);
16         exit(1);
17     }
18     int serverSock;
19     struct sockaddr_in serverAddr, clientAddr;
20     socklen_t clientAddrSize;
21 
22     char message[BUF_SIZE];
23     int strLen;
24 
25     serverSock =socket(PF_INET, SOCK_DGRAM, 0);
26     if(serverSock == -1)
27         error_handling("socket() error");
28 
29     memset(&serverAddr, 0, sizeof(serverAddr));
30     serverAddr.sin_family = AF_INET;
31     serverAddr.sin_addr.s_addr = htonl(INADDR_ANY);
32     serverAddr.sin_port = htons(atoi(argv[1]));
33 
34     if(bind(serverSock, (struct sockaddr*) &serverAddr, sizeof(serverAddr)) == -1)
35         error_handling("bind() error");
36 
37     puts("Server start...");
38     while(1){
39         clientAddrSize = sizeof(clientAddr);
40         strLen = recvfrom(serverSock, message, BUF_SIZE, 0, (struct sockaddr*) &clientAddr, &clientAddrSize);
41         sendto(serverSock, message, strLen, 0, (struct sockaddr*)&clientAddr, clientAddrSize);
42     }
43     close(serverSock);
44     puts("Server close...");
45     return 0;
46 }
47 
48 void error_handling(char * messages)
49 {
50     puts(messages);
51     exit(1);
52 }
View Code

客户端:

 1 #include <stdio.h>
 2 #include <stdlib.h>
 3 #include <string.h>
 4 #include <unistd.h>
 5 #include <arpa/inet.h>
 6 #include <sys/socket.h>
 7 
 8 #define BUF_SIZE 1024
 9 void error_handling(char * messages);
10 
11 int main(int argc, char *argv[])
12 {
13     if(argc != 3)
14     {
15         printf("Usage : %s <IP> <port>
", argv[0]);
16         exit(1);
17     }
18     int sock;
19     struct sockaddr_in serv_addr, from_addr;
20     socklen_t addr_size;
21     char message[BUF_SIZE];
22     int strLen;
23 
24     sock = socket(PF_INET, SOCK_DGRAM, 0);
25     if(sock == -1)
26         error_handling("socket() error");
27 
28     memset(&serv_addr, 0, sizeof(serv_addr));
29     serv_addr.sin_family = AF_INET;
30     serv_addr.sin_addr.s_addr = inet_addr(argv[1]);
31     serv_addr.sin_port = htons(atoi(argv[2]));
32 
33     while(1){
34         puts("Input message(Q to quit):");
35         fgets(message, BUF_SIZE, stdin);
36         if(!strcmp(message, "q
") || !strcmp(message, "Q
"))
37             break;
38         sendto(sock, message, strlen(message), 0, (struct sockaddr*)&serv_addr,sizeof(serv_addr));
39         addr_size = sizeof(from_addr);
40         strLen = recvfrom(sock, message, BUF_SIZE, 0, (struct sockaddr*)&from_addr, &addr_size);
41         message[strLen]=0;
42         printf("Message from server: %s
", message);
43     }
44     close(sock);
45     return 0;
46 }
47 
48 void error_handling(char * messages)
49 {
50     puts(messages);
51     exit(1);
52 }
View Code

2、windows

服务器端:

 1 #include <stdio.h>
 2 #include <stdlib.h>
 3 #include <WinSock2.h>
 4 
 5 #define BUF_SIZE 1024
 6 void ErrorHandling(char *message);
 7 
 8 int main(int argc, char *argv[])
 9 {
10     if (argc != 2) {
11         printf("Usage : %s <port>
", argv[0]);
12         exit(1);
13     }
14 
15     WSADATA wsa_data;
16     SOCKET server_sock;
17     SOCKADDR_IN server_addr, client_addr;
18     int sz_client_addr;
19     char message[BUF_SIZE];
20     int str_len;
21 
22     if (WSAStartup(MAKEWORD(2, 2), &wsa_data) != 0)
23         ErrorHandling("WSAStartup() error.");
24 
25     server_sock = socket(PF_INET, SOCK_DGRAM, 0);
26     if (server_sock == INVALID_SOCKET)
27         ErrorHandling("socket() error.");
28 
29     memset(&server_addr, 0, sizeof(server_addr));
30     server_addr.sin_family = AF_INET;
31     server_addr.sin_addr.s_addr = htonl(INADDR_ANY);
32     server_addr.sin_port = htons(atoi(argv[1]));
33 
34     if (bind(server_sock, (SOCKADDR*)&server_addr, sizeof(server_addr)) == SOCKET_ERROR)
35         ErrorHandling("bind() error.");
36     printf("Server start...
");
37     while (true)
38     {
39         sz_client_addr = sizeof(client_addr);
40         str_len = recvfrom(server_sock, message, BUF_SIZE, 0, (SOCKADDR*)&client_addr, &sz_client_addr);
41         sendto(server_sock, message, str_len, 0, (SOCKADDR*)&client_addr, sizeof(message));
42     }
43     closesocket(server_sock);
44     printf("Server end...
");
45     WSACleanup();
46     return 0;
47 }
48 
49 void ErrorHandling(char *message) {
50     fputs(message, stderr);
51     fputc('
', stderr);
52 }
View Code

使用连接connected套接字的客户端:

  针对UDP套接字调用connect函数并不意味着要与对方UDP套接字连接,这只是向UDP套接字注册目标IP和端口信息。

 1 #include <stdio.h>
 2 #include <stdlib.h>
 3 #include <string.h>
 4 #include <winsock2.h>
 5 
 6 #define BUF_SIZE 1024
 7 void ErrorHandling(char *message);
 8 
 9 int main(int argc, char* argv[]) {
10     if (argc != 3) {
11         printf("Usage : %s <IP> <port>
", argv[0]);
12         exit(1);
13     }
14 
15     WSADATA wsa_data;
16     SOCKET h_socket;
17     SOCKADDR_IN server_addr;
18 
19     char message[BUF_SIZE];
20     int str_len;
21 
22     if (WSAStartup(MAKEWORD(2, 2), &wsa_data) != 0)
23         ErrorHandling("WSAStartup() error.");
24 
25     h_socket = socket(PF_INET, SOCK_DGRAM, 0);
26     if (h_socket == INVALID_SOCKET)
27         ErrorHandling("socket() error.");
28 
29     memset(&server_addr, 0, sizeof(server_addr));
30     server_addr.sin_family = AF_INET;
31     server_addr.sin_addr.s_addr = inet_addr(argv[1]);
32     server_addr.sin_port = htons(atoi(argv[2]));
33 
34     if (connect(h_socket, (SOCKADDR*)&server_addr, sizeof(server_addr)) == SOCKET_ERROR)
35         ErrorHandling("connect() error.");
36 
37     while (true)
38     {
39         fputs("Insert message(q to quit): ", stdout);
40         fgets(message, sizeof(message), stdin);
41         if (!strcmp(message, "q
") || !strcmp(message, "Q
"))
42             break;
43         send(h_socket, message, strlen(message), 0);
44         str_len = recv(h_socket, message, sizeof(message) - 1, 0);
45         message[str_len] = 0;
46         printf("Message from server: %s", message);
47     }
48     closesocket(h_socket);
49     WSACleanup();
50     return 0;
51 }
52 
53 void ErrorHandling(char *message) {
54     fputs(message, stderr);
55     fputc('
', stderr);
56 }
View Code

使用未连接套接字的客户端:

 1 #include <stdio.h>
 2 #include <stdlib.h>
 3 #include <string.h>
 4 #include <winsock2.h>
 5 
 6 #define BUF_SIZE 1024
 7 void ErrorHandling(char *message);
 8 
 9 int main(int argc, char* argv[]) {
10     if (argc != 3) {
11         printf("Usage : %s <IP> <port>
", argv[0]);
12         exit(1);
13     }
14 
15     WSADATA wsa_data;
16     SOCKET h_socket;
17     SOCKADDR_IN server_addr, from_addr;
18 
19     char message[BUF_SIZE];
20     int str_len;
21 
22     if (WSAStartup(MAKEWORD(2, 2), &wsa_data) != 0)
23         ErrorHandling("WSAStartup() error.");
24 
25     h_socket = socket(PF_INET, SOCK_DGRAM, 0);
26     if (h_socket == INVALID_SOCKET)
27         ErrorHandling("socket() error.");
28 
29     memset(&server_addr, 0, sizeof(server_addr));
30     server_addr.sin_family = AF_INET;
31     server_addr.sin_addr.s_addr = inet_addr(argv[1]);
32     server_addr.sin_port = htons(atoi(argv[2]));
33 
34     while (true)
35     {
36         fputs("Insert message(q to quit): ", stdout);
37         fgets(message, sizeof(message), stdin);
38         if (!strcmp(message, "q
") || !strcmp(message, "Q
"))
39             break;
40         sendto(h_socket, message, strlen(message), 0, (SOCKADDR*)&server_addr, sizeof(server_addr));
41         int sz_from_addr = sizeof(from_addr);
42         str_len = recvfrom(h_socket, message, BUF_SIZE, 0, (SOCKADDR*)&from_addr, &sz_from_addr);
43         message[str_len] = 0;
44         printf("Message from server: %s", message);
45     }
46     closesocket(h_socket);
47     WSACleanup();
48     return 0;
49 }
50 
51 void ErrorHandling(char *message) {
52     fputs(message, stderr);
53     fputc('
', stderr);
54 }
View Code
原文地址:https://www.cnblogs.com/ACGame/p/9908215.html