UDP客户端使用connect与UDP服务器使用send函数和recv函数收发数据

服务器代码编译运行

服务器udpconnectToServer.c的代码如下:

c 复制代码
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<unistd.h>
#include<arpa/inet.h>
#include<sys/socket.h>
#include<errno.h>
#include<syslog.h> 
#include<signal.h>
#define    MAXLINE     4096

static int count;

static void quitHere(int signo) {
    printf("\nreceived %d datagrams\n", count);
    exit(0);
}

int main(int argc, char **argv) {
    int socket_fd;
    socket_fd = socket(AF_INET, SOCK_DGRAM, 0);

    struct sockaddr_in server_addr;
    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(atoi(argv[1]));

    bind(socket_fd, (struct sockaddr *) &server_addr, sizeof(server_addr));

    socklen_t client_len;
    char message[MAXLINE];
    message[0] = 0;
    count = 0;

    signal(SIGINT, quitHere);

    struct sockaddr_in client_addr;
    client_len = sizeof(client_addr);
	 // recvfrom会把客户端返回对端发送方的地址和端口等信息放到client_addr和client_len中
    int n = recvfrom(socket_fd, message, MAXLINE, 0, (struct sockaddr *) &client_addr, &client_len);
    if (n < 0) {
        fprintf(stderr, "error in recvfrom function: %s (%d)\n", strerror(errno), errno);
    }
    message[n] = 0;
    printf("received length is %d bytes \ncontent: %s\n", n, message);

    if (connect(socket_fd, (struct sockaddr *) &client_addr, client_len)) {
        fprintf(stderr, "connect error: %s (%d)\n", strerror(errno), errno);
    }

    while (strncmp(message, "quit", 4) != 0) {
        char send_line[MAXLINE];
        sprintf(send_line, "Hi, %s", message);

        size_t rt = send(socket_fd, send_line, strlen(send_line), 0);
        if (rt < 0) {
            fprintf(stderr, "send error: %s (%d)\n", strerror(errno), errno);
        }
        printf("send bytes: %zu \n", rt);

        size_t rc = recv(socket_fd, message, MAXLINE, 0);
        if (rc < 0) {
            fprintf(stderr, "recv error: %s (%d)\n", strerror(errno), errno);
        }
        
        count++;
    }

    exit(0);
}

gcc udpconnectserver.c -o udpconnectserver进行编译,./udpconnectserver 8080运行。

客户端代码编译与运行

客户端udpconnectToServer.c的代码如下:

c 复制代码
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<unistd.h>
#include<arpa/inet.h>
#include<sys/socket.h>
#include<errno.h>
#include<syslog.h>
# define    MAXNUMBER     4096

int main(int argc, char **argv) {
    if (argc != 3) {
        printf("usage: udpclient1 <IPaddress> or <Port>");
    }

    int socket_fd;
    socket_fd = socket(AF_INET, SOCK_DGRAM, 0);

    struct sockaddr_in server_addr;
    bzero(&server_addr, sizeof(server_addr));
    server_addr.sin_family = AF_INET;
    server_addr.sin_port = htons(atoi(argv[2]));
    inet_pton(AF_INET, argv[1], &server_addr.sin_addr);

    socklen_t server_len = sizeof(server_addr);

    if (connect(socket_fd, (struct sockaddr *) &server_addr, server_len)) {
        printf("fail in connect");
        exit(1);
    }

    struct sockaddr *reply_addr;
    reply_addr = malloc(server_len);

    char sendLine[MAXNUMBER], receiveLine[MAXNUMBER + 1];
    socklen_t len;
    int n;

    while (fgets(sendLine, MAXNUMBER, stdin) != NULL) {
        int i = strlen(sendLine);
        if (sendLine[i - 1] == '\n') {
            sendLine[i - 1] = 0;
        }

        printf("send Content: %s\n", sendLine);
        size_t rt = send(socket_fd, sendLine, strlen(sendLine), 0);
        if (rt < 0) {
            printf("error in sending");
        }
        printf("send Content's bytes: %zu \n", rt);

        len = 0;
        receiveLine[0] = 0;
         n = recv(socket_fd, receiveLine, MAXNUMBER, 0);
        if (n < 0){
            if (errno){
                    fprintf(stderr, "error in recvfrom: %s (%d)\n", strerror(errno), errno);
            }else{
                printf("recvfrom not success");
            }
        }
        receiveLine[n] = 0;
        fputs(receiveLine, stdout);
        fputs("\n", stdout);
    }

    exit(0);
}

gcc udpconnectToServer.c -o udpconnectToServer进行编译,./udpconnectToServer 127.0.0.1 8080运行。

实验

这里打开两个终端,然后连接到同一个机器上边。

然后在客户端发送一条信息good,可以看到服务器上收到了good并且给客户端发送了Hi, good。

以quit开头的字符串从客户端发送过来之后,就会让服务器关闭。

此文章为11月Day 23学习笔记,内容来源于极客时间《网络编程实战》。

相关推荐
Shadow(⊙o⊙)3 分钟前
仿muduo实现高并发服务器——读写缓冲区Buffer.hpp
运维·服务器
C++ 老炮儿的技术栈12 分钟前
char 造成的数据溢出
linux·服务器·c语言·c++·算法·c
qetfw14 分钟前
Bash 内置与外部命令:type、command 与 builtin 验证
linux·开发语言·bash
虚无的纽扣14 分钟前
【Linux】信号(上):一个进程是怎么“被通知”的
linux·运维·驱动开发
是枚小菜鸡儿吖26 分钟前
听歌截图太普通?我把MusicCard部署到极空间,把歌曲做成随时可开的音乐海报页
服务器·人工智能·后端·ai·大模型
虎鲸不是鱼35 分钟前
【虎鲸进化论 13】CI/CD:它在服务器上铺了条流水线
服务器·人工智能·ci/cd·大模型·自进化agent
大哥您好9 小时前
QEMU 11.1.2 多架构编译指南(x86_64 / aarch64 / riscv64)
linux·服务器
道满科技10 小时前
Function Calling 参数总出错?只修参数就行
linux·windows·python
Gauss松鼠会11 小时前
高斯数据库(openGauss)的物理存储结构
运维·服务器·数据库·sql·opengauss·经验总结
Android系统攻城狮11 小时前
Linux Gstreamer深度解析之gst_audio_ring_buffer_prepare_read调用流程与实战(七十四)
linux·运维·服务器·gstreamer音视频·音视频进阶