Linux UDP 收发实例

首先我们需要一个 struct.h

#ifndef STRUCT_H
#define STRUCT_H

typedef struct _UDP_MSG {
    int add1;
    int add2;
    int sum;
    char str1[128];
    char str2[128];
    char cat[256];
} UDP_MSG;

#endif /* STRUCT_H */

然后是服务端的

#include <sys/types.h>
#include <sys/socket.h>
#include <string.h>
#include <netinet/in.h>
#include <stdio.h>
#include <stdlib.h>

#include "struct.h"

#define MAX_LINE 1024
#define SERV_PORT 8080

int udp_serv();

int main() {
    return udp_serv();
}

int udp_serv() {
    int sockfd = socket(AF_INET, SOCK_DGRAM, 0);
    if (sockfd == -1) {
        perror("socket");
        return -1;
    }
    
    struct sockaddr_in serv_addr;
    memset(&serv_addr, 0, sizeof(serv_addr));
    serv_addr.sin_family = AF_INET;
    serv_addr.sin_addr.s_addr = htonl(INADDR_ANY);
    serv_addr.sin_port = htons(SERV_PORT);

    if (bind(sockfd, (struct sockaddr*)&serv_addr, sizeof(serv_addr)) == -1) {
        perror("bind");
        return -1;
    }

    while (1) {
        struct sockaddr_in cli_addr;
        memset(&cli_addr, 0, sizeof(cli_addr));
        UDP_MSG msg;
        memset(&msg, 0, sizeof(msg));
        socklen_t cli_addr_len = sizeof(cli_addr);
        recvfrom(sockfd, &msg, sizeof(msg), 0, (struct sockaddr*)&cli_addr, &cli_addr_len);
        msg.sum = msg.add1 + msg.add2;
        strcpy(msg.cat, msg.str1);
        strcat(msg.cat, msg.str2);
        printf("msg.add1 is: %d\n", msg.add1);
        printf("msg.add2 is: %d\n", msg.add2);
        printf("msg.sum is: %d\n", msg.sum);
        printf("msg.str1 is: %s\n", msg.str1);
        printf("msg.str2 is: %s\n", msg.str2);
        printf("msg.cat is: %s\n", msg.cat);
        sendto(sockfd, &msg, sizeof(msg), 0, (struct sockaddr*)&cli_addr, cli_addr_len);
    }

    return 0;
}

然后是客户端的

#include <sys/types.h>
#include <sys/socket.h>
#include <string.h>
#include <netinet/in.h>
#include <stdio.h>
#include <stdlib.h>
#include <arpa/inet.h>
#include <unistd.h>

#include "struct.h"

#define MAX_LINE 1024
#define SERV_PORT 8080

int udp_cli(const char* serv_ip);

int main(int argc, char* argv[]) {
    if (argc < 2) {
        printf("Usage: %s serv_ip\n", argv[0]);
        return 1;
    }
    return udp_cli(argv[1]);
}

int udp_cli(const char* serv_ip) {
    int sockfd = socket(AF_INET, SOCK_DGRAM, 0);
    if (sockfd == -1) {
        perror("socket");
        return -1;
    }
    struct sockaddr_in serv_addr;
    memset(&serv_addr, 0, sizeof(serv_addr));
    serv_addr.sin_family = AF_INET;
    serv_addr.sin_port = htons(SERV_PORT);
    if (inet_pton(AF_INET, serv_ip, &serv_addr.sin_addr) <= 0) {
        perror("inet_pton");
        return -1;
    }
    while (1) {
        UDP_MSG msg;
        memset(&msg, 0, sizeof(msg));
        msg.add1 = 1;
        msg.add2 = 2;
        sprintf(msg.str1, "hello ");
        sprintf(msg.str2, "world");
        if (sendto(sockfd, &msg, sizeof(msg), 0,
            (struct sockaddr*)&serv_addr, sizeof(serv_addr)) == -1) {
            perror("write");
            return -1;
        }
        socklen_t serv_addr_len = sizeof(serv_addr);
        if (recvfrom(sockfd, &msg, sizeof(msg), 0,
            (struct sockaddr*)&serv_addr, &serv_addr_len) == -1) {
            perror("read");
            return -1;
        }
        printf("msg.add1 is: %d\n", msg.add1);
        printf("msg.add2 is: %d\n", msg.add2);
        printf("msg.sum is: %d\n", msg.sum);
        printf("msg.str1 is: %s\n", msg.str1);
        printf("msg.str2 is: %s\n", msg.str2);
        printf("msg.cat is: %s\n", msg.cat);
        break;
    }
    return 0;
}

客户端另外一种,像这样的写法也行。。

#include <sys/types.h>
#include <sys/socket.h>
#include <string.h>
#include <netinet/in.h>
#include <stdio.h>
#include <stdlib.h>
#include <arpa/inet.h>
#include <unistd.h>

#include "struct.h"

#define MAX_LINE 1024
#define SERV_PORT 8080

int udp_cli(const char* serv_ip);

int main(int argc, char* argv[]) {
    if (argc < 2) {
        printf("Usage: %s serv_ip\n", argv[0]);
        return 1;
    }
    return udp_cli(argv[1]);
}

int udp_cli(const char* serv_ip) {
    int sockfd = socket(AF_INET, SOCK_DGRAM, 0);
    if (sockfd == -1) {
        perror("socket");
        return -1;
    }
    struct sockaddr_in serv_addr;
    memset(&serv_addr, 0, sizeof(serv_addr));
    serv_addr.sin_family = AF_INET;
    serv_addr.sin_port = htons(SERV_PORT);
    if (inet_pton(AF_INET, serv_ip, &serv_addr.sin_addr) <= 0) {
        perror("inet_pton");
        return -1;
    }
    if (connect(sockfd, (struct sockaddr*)&serv_addr, sizeof(serv_addr)) == -1) {
        perror("connect");
        return -1;
    }
    while (1) {
        UDP_MSG msg;
        memset(&msg, 0, sizeof(msg));
        msg.add1 = 1;
        msg.add2 = 2;
        sprintf(msg.str1, "hello ");
        sprintf(msg.str2, "world");
        if (write(sockfd, &msg, sizeof(msg)) == -1) {
            perror("write");
            return -1;
        }
        if (read(sockfd, &msg, sizeof(msg)) == -1) {
            perror("read");
            return -1;
        }
        printf("msg.add1 is: %d\n", msg.add1);
        printf("msg.add2 is: %d\n", msg.add2);
        printf("msg.sum is: %d\n", msg.sum);
        printf("msg.str1 is: %s\n", msg.str1);
        printf("msg.str2 is: %s\n", msg.str2);
        printf("msg.cat is: %s\n", msg.cat);
        break;
    }
    return 0;
}

然后编译

g++ -Wall -g serv.cpp -o serv.exe
g++ -Wall -g cli.cpp -o cli.exe

就可以运行了

One thought on “Linux UDP 收发实例

Leave a Reply

Your email address will not be published. Required fields are marked *