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;
}
相关推荐
折哥的程序人生 · 物流技术专研10 小时前
Java面试85题图解版 · 特别篇:2026后端高频面试题复盘(算法底层逻辑+高并发架构设计全解析,附Java实战代码)
java·网络·数据库·算法·面试
c2385610 小时前
Linux C++ 进度条进阶美化与工程化封装
linux·运维·服务器
专注VB编程开发20年10 小时前
c#Modbus上位机开发-一次读10个地址和100个地址速度一样
网络·网络协议·tcp/ip
玖玥拾11 小时前
C/C++ 基础笔记(十四)多态与模板编程
c语言·c++·多态·模板
Roann_seo%11 小时前
C++文件操作完全指南:从文本读写到二进制文件处理
开发语言·c++
坚果派·白晓明12 小时前
【鸿蒙PC】SDL3 适配:AtomCode + Skills 快速集成 NAPI 测试工具
c++·华为·ai编程·harmonyos·atomcode
凡人叶枫13 小时前
Effective C++ 条款17:以独立语句将 newed 对象置入智能指针
java·linux·开发语言·c++·算法
RisunJan13 小时前
Linux命令-pgrep (通过进程名查找进程 ID)
linux·运维
2601_9619633813 小时前
技术解剖:哈希值、区块链与CA认证如何守护电子合同安全?
网络·人工智能·安全·区块链·智能合约·政务
2601_9619633813 小时前
从“电子化”到“自动化”:2026年智能合约与电子合同融合的技术逻辑与法律适配
网络·人工智能·区块链·智能合约·政务