zoukankan      html  css  js  c++  java
  • 回声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
  • 相关阅读:
    n&(n-1)计算比特位1的个数的原理
    gentoo安装apache、nginx、php、mariadb、openssl(https)
    记一次基于vmware的gentoo安装
    Nim 游戏 -(拿石头游戏)
    八皇后问题(N皇后问题)
    ARM架构和Cortex的关系
    某些STM32芯片在开启看门狗后仿真到断点处看门狗不会停止计数导致程序复位的问题
    STM32F103 PB3,PB4特殊引脚的配置
    pc端自适应方案
    左右躲避障碍-神手ts版本
  • 原文地址:https://www.cnblogs.com/ACGame/p/9908215.html
Copyright © 2011-2022 走看看