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;
}
相关推荐
g3voip几秒前
工业防爆电话选型指南:防爆参数、SIP接入与调度系统集成
linux·服务器·网络·信息与通信·ip·pbx
沫璃染墨6 分钟前
《从零入门Linux系统篇(十四):系统工具篇·五——Git版本控制:从版本管理到协同开发》
linux·运维·服务器·git·gitee·github
PGCCC13 分钟前
Ubuntu 安装 PostgreSQL 16 完整教程(2026):从仓库配置到远程连接
linux·ubuntu·postgresql
常乐か1 小时前
在 Ubuntu 24.04 中编译 Qt 5.15.2 项目完全指南
linux·qt·ubuntu
郝学胜-神的一滴1 小时前
中级OpenGL教程 030:gl_FragCoord解锁区域渲染与深度可视化新姿势
c++·unity·游戏引擎·图形渲染·unreal engine·opengl
不会代码的小猴2 小时前
11. 类和动态内存分配
开发语言·c++
探物 AI2 小时前
yolov6的骨干网络组件18:RepVGG,多分支进行训练,单分支进行推理(我有了SCI的主意)
网络·深度学习·yolo
垂直昵称2 小时前
多线程实现网页接口并发压力测试
linux·服务器·windows
鱼子星_2 小时前
【C++】stack和queue的应用及其模拟实现:适配器与容器适配器
数据结构·c++·笔记·stl
jufeng13073 小时前
【系列:MiniKV 原理剖析 · 第 2 篇】
linux·c++·软件工程