Linux下网络编程-简易poll服务器和客户端

Linux下网络编程-简易poll服务器和客户端

简易poll服务器:
cpp 复制代码
//编译命令:g++ -g xxx.cpp -o xxx
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <arpa/inet.h>
#include <sys/socket.h>
#include <poll.h>

int main(int argc, char *argv[])
{
	// 1.创建套接字
    int serv_sock=socket(PF_INET, SOCK_STREAM, 0);
    struct sockaddr_in serv_adr;
	memset(&serv_adr, 0, sizeof(serv_adr));
	serv_adr.sin_family=AF_INET;
	serv_adr.sin_addr.s_addr=htonl(INADDR_ANY);
	serv_adr.sin_port=htons(atoi(argv[1]));
	
	// 2. 绑定 ip, port
    if(bind(serv_sock, (struct sockaddr*) &serv_adr, sizeof(serv_adr))==-1)
		error_handling("bind() error");
	// 3. 监听
	if(listen(serv_sock, 5)==-1)
		error_handling("listen() error");

     //4 等待连接->循环
    //检测->都缓冲区,委托内核去处理
    //数据初始化,创建自定义得文件描述集
    struct pollfd fds[1024];
    //初始化
    for(int i=0;i<1024;i++)
    {
        fds[i].fd=-1;
        fds[i].events=POLLIN;
    }
    fds[0].fd=serv_sock;

    int maxfd=0;
    while (1) 
    {
        //委托内核检测
        if(poll(fds, maxfd+1, -1)==-1)
        {
            perror("select");
            exit(0);
        }

        //检测的度缓冲区有变化
        //有新连接
        if(fds[0].revents&POLLIN)
        {
            // 接收连接请求
            struct sockaddr_in sockcli;
            socklen_t len = sizeof(sockcli);
            // 这个accept是不会阻塞的
            int connfd = accept(serv_sock, (struct sockaddr*)&sockcli, &len);
            //委托内核检测connfd的读缓冲区
            int i;
            for(i=0;i<1024;i++)
            {
                if(fds[i].fd==-1)
                {
                    fds[i].fd=connfd;
                    break;
                }
            }
            maxfd=i>maxfd?i:maxfd;
        }
        //通信。有客户端发送数据过来
        for(int i=1;i<=maxfd;i++)
        {
            //如果在集合中,说明都缓冲区有数据
            if(fds[i].revents&POLLIN)
            {
                char buf[128];
                int ret = read(fds[i].fd, buf, sizeof(buf));
                if(ret == -1)
                {
                    perror("read");
                    exit(0);
                }
                else if(ret == 0)
                {
                    printf("对方已经关闭了连接...\n");
                    close(fds[i].fd);
                    fds[i].fd = -1;
                }
                else
                {
                    printf("客户端say: %s\n", buf);
                    write(fds[i].fd, buf, strlen(buf)+1);
                }
            }
        }
    }
    close(serv_sock);
    return 0;
}
简易客户端:
cpp 复制代码
//编译命令:g++ -g xxx.cpp -o xxx
#include <netinet/in.h>
#include <cstdio>
#include <iostream>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <arpa/inet.h>
#include <sys/select.h>
#include <poll.h>
using namespace std;

int main()
{
    //创建socket对象
    int Client = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
    if (Client == -1)//判断是否创建成功
    {
        cout << "创建失败" << endl;
        close(Client);
        return -1;
    }

    const char* ip = "127.0.0.1";//保存ip地址
    unsigned short port=9527;//保存端口

    //设置服务端
    sockaddr_in addrServer;
    addrServer.sin_addr.s_addr = inet_addr(ip);
    addrServer.sin_port = htons(port);
    addrServer.sin_family = AF_INET;

    //连接
    if (connect(Client, (sockaddr*)&addrServer, sizeof(addrServer))== -1)
    {
        cout << "连接失败" << endl;
        close(Client);
        return -1;
    }
    cout << "连接服务器成功" << endl;

    //接收和发送数据
    char rec[1024];
    char se[1024];

    while(1)
    {
        memset(rec, 0, sizeof(rec));
        memset(se, 0, sizeof(se));
        
        scanf("%s", se);
        if (strcmp(se, "quit") == 0 || strcmp(se, "exit") == 0)
            break;

        if (send(Client, se, sizeof(se), 0) < 0)
            break;
        cout << "发送:" << se << endl;

        if (recv(Client, rec, sizeof(rec), 0) < 0)
            break;
        cout << "接收:" << rec << endl;
    }

    cout << "已与服务端断开连接" << endl;

    close(Client);
    return 0;
}
相关推荐
wdfk_prog16 小时前
嵌入式面试真题第 10 题:高优化等级下共享状态可见性、内存模型与系统级同步设计
java·linux·开发语言·面试·职场和发展·架构·c
x-cmd18 小时前
Mac 涨价后,本地 AI 还能千元入门吗?
linux·人工智能·macos·ai·agent·amd·本地ai入门
楷哥爱开发18 小时前
如何使用 Claude Fable 5 进行网页抓取?2026最新实战教程
大数据·网络·人工智能
Sirius Wu19 小时前
OpenClaw Skill:Matplotlib 可视化技能 + 沙箱双层隔离完整详解
服务器·网络·人工智能·安全·ai·架构·aigc
闻道且行之19 小时前
TurboOCR:基于PP-OCRv6的极速Windows离线OCR工具,深度解析3.4GB依赖背后的技术架构
c++·人工智能·python·qt·机器学习·ocr
酣大智19 小时前
常用 IP 协议号大全(IP 层承载的上层协议)
网络·网络协议·tcp/ip
c2385621 小时前
Bug 猎手入门指南
c++·算法·bug
大公产经晚间消息1 天前
《寻访独角兽》首期走进太仓,探访小科智行的硬科技“突围”
网络·人工智能·科技
JoyCong19981 天前
ToDesk新功能科普:屏幕墙、协作模式、设备别名、USB映射...
网络·科技·电脑·远程工作·远程操作
玖玥拾1 天前
C++ 数据结构 八大基础排序算法专题
数据结构·c++·算法·排序算法