#includesys/types.h#includesys/socket.h#includestdio.h# #include #include #include #include #include #include #include #include #include #include #include #include #include #include int Socket(int domain,int type,int protocol); int Bind(in
#includesys/types.h#includesys/socket.h#includestdio.h#
#include #include #include #include #include #include #include #include #include #include #include #include #include #include
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*)//允许套接字重用,主要用于服务器套接字,放在bind之前。 //绑定服务器信息 int addrlen = sizeof(SIN); Bind(socketid, (SA*) //监听 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, 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 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) //获取协议尾部 if(((unsigned char)readp[len-1]==0xff) //发送方设备节点编号 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) //在线 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= } else { readp++; //粘包处理 } } else { readp++; //粘包处理 } } }
版权声明:本文为m0_60098592原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。原文链接:https://blog.csdn.net/m0_60098592/article/details/119522333