• 回声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
  • 相关阅读:
    如何实时抓取动态网页数据?
    产品经理面试——简历填写
    项目章程
    IDEA 必要配置
    项目章程
    基础知识02 零基础入门学习汇编语言02
    基础知识03 零基础入门学习汇编语言03
    进制转换教程
    基础知识04 零基础入门学习汇编语言04
    基础知识01 零基础入门学习汇编语言01
  • 原文地址:https://www.cnblogs.com/ACGame/p/9908215.html
Copyright © 2020-2023  润新知