#include<sys/types.h> #include<sys/socket.h> #include<stdio.h> #include<stdlib.h> #include<string.h> #include<netinet/in.h>? #include <unistd.h> #include <arpa/inet.h> #include <pthread.h> #include <sys/time.h> #include <sys/types.h> #include <unistd.h> #include <sys/select.h> #include <sys/epoll.h>
int Socket(int domain,int type,int protocol); int Bind(int sockfd,struct sockaddr * my_addr,int addrlen); int Listen(int s,int backlog); int Accept(int s,struct sockaddr * addr,int * addrlen); void Deal_with_len(int recvid,char * readbuff); typedef struct sockaddr SA; ? ? ?//通用地址结构 typedef struct sockaddr_in SIN;//IPV4地址结构 //设备信息列表 typedef struct{ ?? ?int fd; ?? ?int devino; ?? ?int flags; }FDFORDEV; //文件描述符与设备信息列表 FDFORDEV fdfordev[1024]; //app IP地址 端口号 int main(int argc,char**argv) { ?? ?memset(fdfordev,0,sizeof(fdfordev)); ?? ?//建立监听套接字 ?? ?int socketid = Socket(AF_INET,SOCK_STREAM,0); ?? ?//编写服务器信息 ?? ?SIN ?my_addr; ?? ?my_addr.sin_family = AF_INET;?? ?//IPV4协议 ?? ?my_addr.sin_port = htons(atoi(argv[2]));//大端序 ?? ?my_addr.sin_addr.s_addr= inet_addr(argv[1]);//IP地址 ?? ?int reuse=1; setsockopt(socketid,SOL_SOCKET ,SO_REUSEADDR,(const char*)& reuse,sizeof(int));//允许套接字重用,主要用于服务器套接字,放在bind之前。 ?? ?//绑定服务器信息 ?? ?int addrlen = sizeof(SIN); ?? ?Bind(socketid, (SA*)&my_addr,addrlen); ?? ?//监听 ?? ?Listen(socketid,100); ?? ?SIN ?client_addr; ?? ?int client_len = sizeof(SIN); ?? ?/*****************************epoll****************/ ?? ?int epollfd = epoll_create(1024); ?? ?printf("epollfd:%d\n",epollfd); ?? ?struct epoll_event event; ?? ?event.events = EPOLLIN; ?? ?event.data.fd = socketid; ?? ?int val = epoll_ctl(epollfd,EPOLL_CTL_ADD,socketid,&event); ?? ?if(val== -1) ?? ?{ ?? ??? ?perror("epoll_ctl"); ?? ??? ?exit(0); ?? ?} ?? ?//通信 ?? ?while(1) ?? ?{ ?? ??? ?struct epoll_event events[10]; ?? ??? ?int count = epoll_wait(epollfd,events,10,-1); ?? ??? ?if(count > 0) ?? ??? ?{ ?? ??? ??? ?for(int i =0; i < count;i++) ?? ??? ??? ?{ ?? ??? ??? ??? ?//判断 accept ?? ??? ??? ??? ?if(events[i].data.fd == socketid) ?? ??? ??? ??? ?{ ?? ??? ??? ??? ??? ?SIN client; ?? ??? ??? ??? ??? ?struct epoll_event newevent; ?? ??? ??? ??? ??? ?int addrlen = sizeof(SA); ?? ??? ??? ??? ??? ?int newfd = Accept(socketid,(SA*)&client,&addrlen); ?? ??? ??? ??? ??? ?printf("%d客户端连接\n",newfd); ?? ??? ??? ??? ??? ?printf("\033[5m\033[45;33m HELLO_WORLD \033[0m\n"); ?? ??? ??? ??? ??? ?newevent.events=EPOLLIN; ?? ??? ??? ??? ??? ?newevent.data.fd = newfd; ?? ??? ??? ??? ??? ?epoll_ctl(epollfd,EPOLL_CTL_ADD,newfd,&newevent); ?? ??? ??? ??? ?} ?? ??? ??? ??? ?//read ?? ??? ??? ??? ?else? ?? ??? ??? ??? ?{ ?? ??? ??? ??? ??? ?char readbuff[1024]={0}; ?? ??? ??? ??? ??? ?int len = read(events[i].data.fd,readbuff,sizeof(readbuff)); ?? ??? ??? ??? ??? ?if(len >0) ?? ??? ??? ??? ??? ?{ ?? ??? ??? ??? ??? ??? ?printf("%d:%s\n",events[i].data.fd,readbuff); ?? ??? ??? ??? ??? ??? ?Deal_with_len(events[i].data.fd,readbuff); ?? ??? ??? ??? ??? ?} ?? ??? ??? ??? ??? ?else if(len ==0) ?? ??? ??? ??? ??? ?{ ?? ??? ??? ??? ??? ??? ?printf("%d:正常退出\n",events[i].data.fd); ?? ??? ??? ??? ??? ??? ?epoll_ctl(epollfd,EPOLL_CTL_DEL,events[i].data.fd,NULL); ?? ??? ??? ??? ??? ??? ?close(events[i].data.fd); ?? ??? ??? ??? ??? ??? ?fdfordev[events[i].data.fd].fd = 0; ?? ??? ??? ??? ??? ?} ?? ??? ??? ??? ??? ?else ?? ??? ??? ??? ??? ?{ ?? ??? ??? ??? ??? ??? ?printf("%d:异常退出\n",events[i].data.fd); ?? ??? ??? ??? ??? ??? ?epoll_ctl(epollfd,EPOLL_CTL_DEL,events[i].data.fd,NULL); ?? ??? ??? ??? ??? ??? ?close(events[i].data.fd); ?? ??? ??? ??? ??? ??? ?fdfordev[events[i].data.fd].fd =0; ?? ??? ??? ??? ??? ?} ?? ??? ??? ??? ?} ?? ??? ??? ?} ?? ??? ?} ?? ??? ? ?? ?} ?? ? ?? ?return 0; } //包裹函数 int Socket(int domain,int type,int protocol) { ?? ?int socketID ?= socket(domain,type,protocol); ?? ?if(socketID == -1) ?? ?{ ?? ??? ?perror("socket"); ?? ??? ?exit(0); ?? ?} ?? ?return socketID; } int Bind(int sockfd,struct sockaddr * my_addr,int addrlen) { ?? ?int val = bind(sockfd,my_addr,addrlen); ?? ?if(val == -1) ?? ?{ ?? ??? ?perror("bind"); ?? ??? ?exit(0); ?? ?} ?? ?return 0; } int Listen(int s,int backlog) { ?? ?int val = listen(s,backlog); ?? ?if(val == -1) ?? ?{ ?? ??? ?perror("bind"); ?? ??? ?exit(0); ?? ?} ?? ?return 0; } int Accept(int s,struct sockaddr * addr,int * addrlen) { ?? ?int Newid = accept(s, addr, addrlen); ?? ?if(Newid == -1) ?? ?{ ?? ??? ?perror("accept"); ?? ??? ?exit(0); ?? ?} ?? ?return Newid; } //0xff 0xfe 0x长度高8位 0x长度低8位 0x自身设备ID高8位 0x自身设备ID低8位 ?0x对方设备ID高8位 0x对方设备ID低8位 ?0x在线状态 内容 ?0xfe ?0xff void Deal_with_len(int recvid,char * readbuff) { ?? ?char * readp = (char *)readbuff; ?? ?while(*readp != 0) ?? ?{ ?? ??? ?//对比协议包头部分 ?? ??? ?if(((unsigned char)readp[0] == 0xff)&&((unsigned char)readp[1] == 0xfe)) ?? ??? ?{ ?? ??? ??? ?//获取整个协议数据长度 ?? ??? ??? ?short len = readp[2]<<8|readp[3]; ?? ??? ??? ?//获取协议尾部 ?? ??? ??? ?if(((unsigned char)readp[len-1]==0xff)&&((unsigned char)readp[len-2]==0xfe)) ?? ??? ??? ?{ ?? ??? ??? ??? ?//发送方文件描述符 ?? ??? ??? ??? ?fdfordev[recvid].fd = recvid; ?? ??? ??? ??? ?//发送方设备节点编号 ?? ??? ??? ??? ?fdfordev[recvid].devino = readp[4]<<8|readp[5]; ?? ??? ??? ??? ?//接收方设备编号 ?? ??? ??? ??? ?short recvdevid = readp[6]<<8|readp[7]; ?? ??? ??? ??? ?//接收方设备编号为0则服务器处理 ?? ??? ??? ??? ?if(recvdevid == 0) ?? ??? ??? ??? ?{ ?? ??? ??? ??? ??? ?//本机操作 ?? ??? ??? ??? ??? ?printf("本机已接到\n"); ?? ??? ??? ??? ?} ?? ??? ??? ??? ?//转发消息 ?? ??? ??? ??? ?else ?? ??? ??? ??? ?{ ?? ??? ??? ??? ??? ?int sendflag =0; ?? ??? ??? ??? ??? ?printf("转发消息\n"); ?? ??? ??? ??? ??? ?//遍历设备信息及文件描述符列表 ?? ??? ??? ??? ??? ?for(int j = 0; j < 1024; j++) ?? ??? ??? ??? ??? ?{ ?? ??? ??? ??? ??? ??? ?if((fdfordev[j].devino == ?devid)&&(fdfordev[j].fd != 0)) ?? ??? ??? ??? ??? ??? ?{ ?? ??? ??? ??? ??? ??? ??? ?readp[8] = 0x01;?? ??? ??? ??? ??? ??? ??? ??? ?//在线 ?? ??? ??? ??? ??? ??? ??? ?write(fdfordev[j].fd,readp,len); ?? ??? ??? ??? ??? ??? ??? ?printf("转发对方\n"); ?? ??? ??? ??? ??? ??? ??? ?break; ?? ??? ??? ??? ??? ??? ?} ?? ??? ??? ??? ??? ??? ?if(j == 1023) ?? ??? ??? ??? ??? ??? ?{ ?? ??? ??? ??? ??? ??? ??? ?sendflag =1; ?? ??? ??? ??? ??? ??? ?} ?? ??? ??? ??? ??? ?} ?? ??? ??? ??? ??? ?//无该设备信息返回发送方不在线协议报 ?? ??? ??? ??? ??? ?if(sendflag) ?? ??? ??? ??? ??? ?{ ?? ??? ??? ??? ??? ??? ?//0xff 0xfe 0x长度高8位 0x长度低8位 0x自身设备ID高8位 0x自身设备ID低8位 ?0x对方设备ID高8位 0x对方设备ID低8位 ?0x在线状态 内容 ?0xfe ?0xff ?? ??? ??? ??? ??? ??? ?readp[8] = 0x00;?? ??? ??? ??? ??? ??? ??? ??? ??? ??? ?//不在线 ?? ??? ??? ??? ??? ??? ?readp[6] = readp[4]; ?? ??? ??? ??? ??? ??? ?readp[7] = readp[5]; ?? ??? ??? ??? ??? ??? ?readp[4]=0xff; ?? ??? ??? ??? ??? ??? ?readp[5]=0xff; ?? ??? ??? ??? ??? ??? ? ?? ??? ??? ??? ??? ??? ?write(recvid,readp,len); ?? ??? ??? ??? ??? ??? ?printf("转发自己\n"); ?? ??? ??? ??? ??? ?} ?? ??? ??? ??? ?} ?? ??? ??? ??? ?readp=&readp[len]; ?? ??? ??? ?} ?? ??? ??? ?else ?? ??? ??? ?{ ?? ??? ??? ??? ?readp++;?? ??? ??? ??? ??? ??? ??? ??? ??? ??? ??? ??? ??? ??? ?//粘包处理 ?? ??? ??? ?} ?? ??? ?} ?? ??? ?else ?? ??? ?{ ?? ??? ??? ?readp++;?? ??? ??? ??? ??? ??? ??? ??? ??? ??? ??? ??? ??? ??? ??? ?//粘包处理 ?? ??? ?} ?? ?} }
|