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;
}
相关推荐
欧特克_Glodon2 小时前
OpenCV计算机视觉开发入门与实践<二十七>:图像分割概述
c++·人工智能·opencv·计算机视觉
蒸蒸yyyyzwd2 小时前
cpp 选手秋招学习笔记 day21
c++·面试·八股
草莓熊Lotso2 小时前
【Redis 初阶】Set 类型深度解析:去重集合的运算能力与实战场景
linux·网络·数据库·windows·redis·tcp/ip·缓存
张文君2 小时前
ubuntu26.04坏道坏块分区隔离急速版260831-V0.12
linux·python
XR1234567883 小时前
汽车制造园区网络怎么建?柔性产线与 AGV 的选型逻辑
网络·汽车·制造
贝锐11 小时前
从国产化信创设备到商用安卓终端,向日葵如何帮助企业实现统一运维管理?
linux·运维·远程控制
IT大白鼠12 小时前
MSF二次开发与自定义模块编写
网络·安全·web安全·msf
Julien200412 小时前
调查和解决 SELinux 问题
linux·运维·服务器·网络·学习方法
「QT(C++)开发工程师」13 小时前
C++ auto 用法详解
开发语言·c++
OPEN-F14 小时前
C++STL教程:容器适配器与实用工具
开发语言·c++