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

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

简易Epll服务器:
cpp 复制代码
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <arpa/inet.h>
#include <sys/socket.h>
#include <sys/epoll.h>

#define BUF_SIZE 100
#define EPOLL_SIZE 50
void error_handling(const char *buf);

int main(int argc, char *argv[])
{
    if(argc!=2) 
    {
		printf("Usage : %s <port>\n", argv[0]);
		exit(1);
	}

    int serv_sock, clnt_sock;
	struct sockaddr_in serv_adr, clnt_adr;
	socklen_t adr_sz;
	int str_len, i;
	char buf[BUF_SIZE];

    serv_sock=socket(PF_INET, SOCK_STREAM, 0);
	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]));

    if(bind(serv_sock, (struct sockaddr*) &serv_adr, sizeof(serv_adr))==-1)
		error_handling("bind() error");
	if(listen(serv_sock, 5)==-1)
		error_handling("listen() error");

    epoll_event event;
    int epfd,event_count;
    epfd=epoll_create(100);
    if(epfd==-1)
    {
        error_handling("epoll_create() failed");
        close(serv_sock);
    }
        
    epoll_event* all_events=new epoll_event[EPOLL_SIZE];
    event.events=EPOLLIN;//默认是设置条件触发方式
    event.data.fd=serv_sock;
    epoll_ctl(epfd,EPOLL_CTL_ADD,serv_sock,&event);

    while(1)
    {
        event_count=epoll_wait(epfd,all_events,EPOLL_SIZE,-1);
        if(event_count==-1)
        {
            puts("epoll_wait() error\n");
            break;
        }

        for(int i=0;i<event_count;i++)
        {
            if(all_events[i].data.fd==serv_sock)
            {
                adr_sz=sizeof(clnt_adr);
                clnt_sock=accept(serv_sock,(struct sockaddr*)&clnt_adr,&adr_sz);
                event.events=EPOLLIN;
                event.data.fd=clnt_sock;
                epoll_ctl(epfd,EPOLL_CTL_ADD,clnt_sock,&event);
                printf("connected client: %d \n", clnt_sock);
            }
            else
            {
                str_len=read(all_events[i].data.fd,buf,BUF_SIZE);
                if(str_len==0)//关闭请求
                {
                    epoll_ctl(epfd,EPOLL_CTL_DEL,all_events[i].data.fd,NULL);
                    close(all_events[i].data.fd);
                    printf("closed client:%d\n",all_events[i].data.fd);
                }   
                else
                {
                    write(all_events[i].data.fd,buf,BUF_SIZE);
                }
            }
        }
    }

    delete[] all_events;
    close(serv_sock);
    close(epfd);
    return 0;
}

void error_handling(const char *buf)
{
	fputs(buf, stderr);
	fputc('\n', stderr);
	exit(1);
}
简易客户端:
cpp 复制代码
//编译命令:g++ -g PThreadSocketClient.cpp -o PThreadSocketClient -lpthread
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <arpa/inet.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <pthread.h>

#define BUF_SIZE 100
#define NAME_SIZE 20

char name[NAME_SIZE]="[DEFAULT]";
char msg[BUF_SIZE];

void* send_msg(void * arg);
void* recv_msg(void * arg);
void error_handling(const char * msg);

int main(int argc, char *argv[])
{
	int sock;
	struct sockaddr_in serv_addr;
	pthread_t snd_thread, rcv_thread;
	void * thread_return;

    if(argc!=4) 
    {
		printf("Usage : %s <IP> <port> <name>\n", argv[0]);
		exit(1);
	 }

	sprintf(name, "[%s]", argv[3]);
	sock=socket(PF_INET, SOCK_STREAM, 0);
	
	memset(&serv_addr, 0, sizeof(serv_addr));
	serv_addr.sin_family=AF_INET;
	serv_addr.sin_addr.s_addr=inet_addr(argv[1]);
	serv_addr.sin_port=htons(atoi(argv[2]));
	  
	if(connect(sock, (struct sockaddr*)&serv_addr, sizeof(serv_addr))==-1)
		error_handling("connect() error");

	pthread_create(&snd_thread,NULL,send_msg,(void*)&sock);
	pthread_create(&rcv_thread,NULL,recv_msg,(void*)&sock);
	pthread_join(snd_thread,&thread_return);
	pthread_join(rcv_thread,&thread_return);
	close(sock);
    return 0;
}

void* send_msg(void * arg)
{
	int sock=*(int *)arg;
	char name_msg[NAME_SIZE+BUF_SIZE];
	while(1)
	{
		fgets(msg,BUF_SIZE,stdin);
		if(!strcmp(msg,"q\n")||!strcmp(msg,"Q\n"))
		{
			close(sock);
			exit(0);
		}
		sprintf(name_msg,"%s %s",name,msg);
		write(sock,name_msg,strlen(name_msg));
	}
	return NULL;
}

void* recv_msg(void * arg)
{
	int sock=*(int *)arg;
	char name_msg[NAME_SIZE+BUF_SIZE];
	int str_len;
	while(1)
	{
		str_len=read(sock,name_msg,NAME_SIZE+BUF_SIZE-1);
		if(str_len==-1)
		{
			return (void*)-1;
		}
		name_msg[str_len]=0;
		fputs(name_msg,stdout);
	}
	return NULL;
}

void error_handling(const char * msg)
{
    fputs(msg, stderr);
	fputc('\n', stderr);
	exit(1);
}
相关推荐
2401_8401052042 分钟前
GESP C++5级 2025年6月编程2题解:最大公因数
数据结构·c++·算法
GUIQU.1 小时前
【QT】高级主题
开发语言·c++·qt
Suger9991 小时前
centos网络打流测试
linux·网络·centos
Cx330❀1 小时前
《C++:STL》详细深入解析string类(一):
开发语言·c++·经验分享
小何好运暴富开心幸福1 小时前
操作系统之初识Linux
linux·运维·服务器·bash
哈泽尔都1 小时前
运动控制教学——5分钟学会样条曲线算法!(三次样条曲线,B样条曲线)
c++·人工智能·算法·机器学习·matlab·贪心算法·机器人
THOVOH2 小时前
C++——类和对象(下)
开发语言·c++
こ进制掌控者2 小时前
Ubuntu server 24.04.3 设置静态IP
linux·tcp/ip·ubuntu
泡沫冰@3 小时前
shell编程:sed - 流编辑器(5)
linux
chenyuhao20243 小时前
vector深度求索(上)实用篇
开发语言·数据结构·c++·后端·算法·类和对象