#include <stdio.h>
#include <sys/types.h>?
#include <sys/socket.h>?
#include <netinet/in.h>?
#include <arpa/inet.h>
#include <stdlib.h>
#include <string.h>
#include <sys/epoll.h>
#define BUFFER_SIZE 40
#define MAX_EVENTS 10
int main(int argc, char * argv[])?
{
? ? int server_sockfd;// 服務(wù)器端套接字?
? ? int connect_fd;// 客戶端套接字?
? ? int len;?
? ? struct sockaddr_in my_addr;? // 服務(wù)器網(wǎng)絡(luò)地址結(jié)構(gòu)體?
? ? struct sockaddr_in remote_addr; // 客戶端網(wǎng)絡(luò)地址結(jié)構(gòu)體?
? ? int sin_size;?
? ? char buf[BUFFER_SIZE];
? ? char sendbuf[BUFFER_SIZE];? // 數(shù)據(jù)傳送的緩沖區(qū)?
? ? memset(&my_addr,0,sizeof(my_addr)); // 數(shù)據(jù)初始化--清零?
? ? my_addr.sin_family=AF_INET; // 設(shè)置為IP通信?
? ? my_addr.sin_addr.s_addr=INADDR_ANY;// 服務(wù)器IP地址--允許連接到所有本地地址上?
? ? my_addr.sin_port=htons(9998); // 服務(wù)器端口號?
? ? // 創(chuàng)建服務(wù)器端套接字--IPv4協(xié)議,面向連接通信,TCP協(xié)議
? ? if((server_sockfd=socket(PF_INET,SOCK_STREAM,0))<0)?
? ? {? ?
? ? ? ? perror("socket");?
? ? ? ? return 1;?
? ? }?
? ? // 將套接字綁定到服務(wù)器的網(wǎng)絡(luò)地址上
? ? if (bind(server_sockfd,(struct sockaddr *)&my_addr,sizeof(struct sockaddr))<0)?
? ? {?
? ? ? ? perror("bind");?
? ? ? ? return 1;?
? ? }?
? ? // 監(jiān)聽連接請求--監(jiān)聽隊(duì)列長度為5
? ? listen(server_sockfd,5);?
? ? sin_size=sizeof(struct sockaddr_in);
? ? int epoll_fd;
? ? epoll_fd=epoll_create(MAX_EVENTS);//創(chuàng)建一個(gè)epoll句柄
? ? if(epoll_fd==-1)
? ? {
? ? ? ? perror("epoll_create failed");
? ? ? ? exit(EXIT_FAILURE);
? ? }
? ? struct epoll_event ev;? // epoll事件結(jié)構(gòu)體 內(nèi)涵兩個(gè)數(shù)據(jù)events與data
? ? struct epoll_event events[MAX_EVENTS];// 事件監(jiān)聽隊(duì)列
? ? ev.events=EPOLLIN;
? ? ev.data.fd=server_sockfd;//結(jié)構(gòu)體內(nèi)嵌聯(lián)合體
? ? // 向epoll注冊server_sockfd監(jiān)聽事件,加入到epoll的監(jiān)聽隊(duì)列中
? ? if(epoll_ctl(epoll_fd,EPOLL_CTL_ADD,server_sockfd,&ev)==-1)
? ? {
? ? ? ? perror("epll_ctl:server_sockfd register failed");
? ? ? ? exit(EXIT_FAILURE);
? ? }
? ? int nfds;// epoll監(jiān)聽事件發(fā)生的個(gè)數(shù)
? ? // 循環(huán)接受客戶端請求? ?
? ? while(1)
? ? {
? ? ? ? // 等待事件發(fā)生
? ? ? ? nfds=epoll_wait(epoll_fd,events,MAX_EVENTS,-1);
? ? ? ? if(nfds==-1)
? ? ? ? {
? ? ? ? ? ? perror("start epoll_wait failed");
? ? ? ? ? ? exit(EXIT_FAILURE);
? ? ? ? }
? ? ? ? int i;
? ? ? ? for(i=0;i<nfds;i++)
? ? ? ? {
? ? ? ? ? ? // 客戶端有新的連接請求
? ? ? ? ? ? if(events[i].data.fd==server_sockfd)
? ? ? ? ? ? {
? ? ? ? ? ? ? ? // 等待客戶端連接請求到達(dá),調(diào)用accept函數(shù)
? ? ? ? ? ? ? ? if((connect_fd=accept(server_sockfd,(struct sockaddr *)&remote_addr,&sin_size))<0)
? ? ? ? ? ? ? ? {?
? ? ? ? ? ? ? ? ? ? perror("accept? failed");?
? ? ? ? ? ? ? ? ? ? exit(EXIT_FAILURE);
? ? ? ? ? ? ? ? }
? ? ? ? ? ? ? ? // 向epoll注冊connect_fd監(jiān)聽事件
? ? ? ? ? ? ? ? ev.events=EPOLLIN;
? ? ? ? ? ? ? ? ev.data.fd=connect_fd;
? ? ? ? ? ? ? ? if(epoll_ctl(epoll_fd,EPOLL_CTL_ADD,connect_fd,&ev)==-1)
? ? ? ? ? ? ? ? {
? ? ? ? ? ? ? ? ? ? perror("epoll_ctl:connect_fd register failed");
? ? ? ? ? ? ? ? ? ? exit(EXIT_FAILURE);
? ? ? ? ? ? ? ? }
? ? ? ? ? ? ? ? printf("accept client %s\n",inet_ntoa(remote_addr.sin_addr));
? ? ? ? ? ? }
? ? ? ? ? ? // 客戶端有數(shù)據(jù)發(fā)送過來
? ? ? ? ? ? else
? ? ? ? ? ? {
? ? ? ? ? ? ? ? len=recv(connect_fd,buf,BUFFER_SIZE,0);
? ? ? ? ? ? ? ? if(len<0)
? ? ? ? ? ? ? ? {
? ? ? ? ? ? ? ? ? ? perror("receive from client failed");
? ? ? ? ? ? ? ? ? ? exit(EXIT_FAILURE);
? ? ? ? ? ? ? ? }
? ? ? ? ? ? ? ? printf("receive from client:%s",buf);
? ? ? ? ? ? ? ? send(connect_fd,"I have received your message.\n",30,0);
? ? ? ? ? ? ? ? memset(buf, 0, sizeof(buf));?
? ? ? ? ? ? ? ? fgets(sendbuf, 4096, stdin);
? ? ? ? ? ? ? ? send(connect_fd, sendbuf, strlen(sendbuf),0);
? ? ? ? ? ? }
? ? ? ? }
? ? }
? ? return 0;?
}?
---------------------
作者:向念博客
來源:CSDN
原文:https://blog.csdn.net/XN6666/article/details/80352057
版權(quán)聲明:本文為博主原創(chuàng)文章融求,轉(zhuǎn)載請附上博文鏈接磷蛹!