Linux socket: udp server and client demo

一、server 端

1)创建socket,指定协议版本(v4,v6)、协议类型(udp、tcp),获得server fd。

2)bind本地地址

(1)通过server fd进行操作

(2)创建并设置sockaddr_in对象,设置对端的地址和端口信息:

server端,不指定具体的client地址,设置为INADDR_ANY

(3)指定监听端口

3)在server fd上启动监听。

4)接收client连接请求

(1)使用循环持续监听client请求

(2)收到client请求后,在server fd上调用accept获得client fd,client sockaddr_in对象

5)使用client fd进行收发数据

二、client 端

1)创建socket,指定协议版本和协议类型,获得server fd。

2)connect()连接服务器

(1)通过上面创建的server fd进行操作

(2)创建并设置sockaddr_in对象,设置对端的地址和端口信息:

client端,需要指定server的ip:port

(3)bind和connect入参相同,server fd, addr, addr_length

accept()函数参数类似,后两个参数为出参

3)完成连接后,通过server fd和服务器收发数据

cpp 复制代码
#include <iostream>
#include <thread>
#include <netinet/in.h>
#include <cstring>
#include <arpa/inet.h>
#include <cassert>

using namespace std;

#define max_line 80
#define port 21339

void server_func() {
    cout << "server begin\n";
    struct sockaddr_in addr;

    // 1. create udp socket and get the server fd
    int server_fd = socket(PF_INET, SOCK_STREAM, 0);
    assert(server_fd != -1);

    bzero(&addr, sizeof(addr));
    addr.sin_family = PF_INET; // v4
    addr.sin_addr.s_addr = htonl(INADDR_ANY); // listen on any local address
    addr.sin_port = htons(port);

    // 2. bind local address with server fd
    bind(server_fd, (struct sockaddr*)&addr, sizeof(addr));

    // 3. start listening on server fd
    int ret = listen(server_fd, 10);
    assert(ret != -1);
    cout << "server: start listening\n";

    struct sockaddr_in client_addr;
    socklen_t len = 0;
    char buf[max_line];
    char addr_str[INET_ADDRSTRLEN];

    // 4. loop and accept client's requests
    int count = 1;
    while(true) {
        cout << "server: begin loop: " << count++ << endl;
        bzero(&client_addr, sizeof(client_addr));
        // 4.1 accept a client's request and get the client fd for interaction
        // listen on server fd and get a client fd through the server fd
        int client_fd = accept(server_fd, (struct sockaddr*)&client_addr, &len);
        assert(client_fd != -1);

        inet_ntop(PF_INET, &client_addr.sin_addr, addr_str, sizeof(addr_str));
        printf("server: accept client -> [%s:%d]\n", addr_str, client_addr.sin_port);

        // 4.2 use the client fd to receive and send data
//        int n = read(client_fd, buf, max_line);
        int n = recv(client_fd, buf, max_line, 0);
        for (int i=0; i<n; i++) {
            buf[i] = toupper(buf[i]);
        }

        write(client_fd, buf, n);

        close(client_fd);
        cout << "server: end a loop.\n";
    }
}

void client_func() {
    cout << "client begin\n";

    const char* msg = "hello";
    char buf[max_line] = {0};

    struct sockaddr_in server_addr;
    bzero(&server_addr, sizeof(server_addr));

//    inet_pton(PF_INET, "127.0.0.1", &server_addr.sin_addr);
    server_addr.sin_family = PF_INET;
    server_addr.sin_addr.s_addr = inet_addr("127.0.0.1");
    server_addr.sin_port = htons(port);

    // 1. create a socket
    int server_fd = socket(PF_INET, SOCK_STREAM, 0);
    assert(server_fd != -1);

    // 2. connect the socket and get the server fd
    int ret = connect(server_fd, (struct sockaddr*)&server_addr, sizeof(server_addr));
    cout << "client: failed to connect server, since: " << strerror(errno) << endl;
    assert(ret != -1);

    int len = strlen(msg);
    // 3. send and receive data through the server fd
//    write(server_fd, msg, len);
    send(server_fd, msg, len, 0);

    read(server_fd, buf, len);
    cout << "read: " << buf << endl;

    cout << "client end\n";
    return;
}

int main() {
    jthread server(server_func);
    jthread client(client_func);

    std::cout << "Hello, World!" << std::endl;
    return 0;
}
相关推荐
AZ996ZA2 小时前
自学linux的第二十一天【DHCP 服务从入门到实战】
linux·运维·服务器·php
_OP_CHEN2 小时前
【Linux系统编程】(二十八)深入 ELF 文件原理:从目标文件到程序加载的完整揭秘
linux·操作系统·编译·c/c++·目标文件·elf文件
rainbow68892 小时前
Linux文件描述符与重定向原理
c++
Fleshy数模2 小时前
MySQL 表创建全攻略:Navicat 图形化与 Xshell 命令行双模式实践
linux·mysql
CodeSheep程序羊2 小时前
拼多多春节加班工资曝光,没几个敢给这个数的。
java·c语言·开发语言·c++·python·程序人生·职场和发展
I'mChloe3 小时前
PTO-ISA 深度解析:PyPTO 范式生成的底层指令集与 NPU 算子执行的硬件映射
c语言·开发语言
神梦流3 小时前
GE 引擎的非标准数据流处理:稀疏张量与自定义算子在图优化中的语义保持
linux·运维·服务器
编程小白20263 小时前
从 C++ 基础到效率翻倍:Qt 开发环境搭建与Windows 神级快捷键指南
开发语言·c++·windows·qt·学习
2的n次方_3 小时前
Runtime 内存管理深化:推理批处理下的内存复用与生命周期精细控制
c语言·网络·架构
嵌入小生0073 小时前
标准IO---核心函数接口延续(嵌入式Linux)
c语言·vscode·vim·嵌入式·小白·标准io·函数接口