#include <stdio.h> #include <stdlib.h> #include <arpa/inet.h> #include <unistd.h> #include <string.h> #include <sys/types.h> #include <sys/socket.h> #include <netinet/in.h> #include <arpa/inet.h> #include <netdb.h> #include <net/if.h> #include <sys/ioctl.h>
#include <signal.h>
#include <sys/epoll.h> #include <unordered_map>
#define SERVERPORT 8080
int sockfd;
int get_local_ip_using_ifconf(char *str_ip) { int sock_fd, intrface; struct ifreq buf[INET_ADDRSTRLEN]; struct ifconf ifc; char *local_ip = NULL; int status = -1; if ((sock_fd = socket(AF_INET, SOCK_DGRAM, 0)) >= 0) { ifc.ifc_len = sizeof(buf); ifc.ifc_buf = (caddr_t)buf; if (!ioctl(sock_fd, SIOCGIFCONF, (char *)&ifc)) { intrface = ifc.ifc_len/sizeof(struct ifreq); while (intrface-- > 0) { if (!(ioctl(sock_fd, SIOCGIFADDR, (char *)&buf[intrface]))) { local_ip = NULL; local_ip = inet_ntoa(((struct sockaddr_in*)(&buf[intrface].ifr_addr))->sin_addr); if(local_ip) { strcpy(str_ip, local_ip); status = 0; if(strcmp("127.0.0.1", str_ip)) { break; } } } } } close(sock_fd); } return status; }
typedef struct clientString { char* ipAdd; int port; } clientStruct;
void SIGINTHandler(int sig) { close(sockfd); printf("\nServer stopping, already closed socket %d. \n", sockfd); exit(EXIT_SUCCESS); }
int main() { struct sockaddr_in server_addr = {0}; struct sockaddr_in client_addr = {0}; char ip_str[20] = {0}; int addrlen = sizeof(client_addr); int ret; char localIPBuf[20];
signal(SIGINT, (sig_t)SIGINTHandler); sockfd = socket(AF_INET, SOCK_STREAM, 0); if (0 > sockfd) { perror("socket error"); exit(EXIT_FAILURE); } server_addr.sin_family = AF_INET; server_addr.sin_addr.s_addr = htonl(INADDR_ANY); server_addr.sin_port = htons(SERVERPORT);
char buf[20]; get_local_ip_using_ifconf(buf); puts(buf);
inet_ntop(AF_INET, &(server_addr.sin_addr), localIPBuf, sizeof(localIPBuf));
ret = bind(sockfd, (struct sockaddr *)&server_addr, sizeof(server_addr)); if (0 > ret) { perror("bind error"); close(sockfd); exit(EXIT_FAILURE); } ret = listen(sockfd, 50); if (0 > ret) { perror("listen error"); close(sockfd); exit(EXIT_FAILURE); } int epfd, connfd; epfd = epoll_create(256); struct epoll_event ev, events[10]; ev.data.fd = sockfd; ev.events = EPOLLIN|EPOLLET|EPOLLOUT; epoll_ctl(epfd, EPOLL_CTL_ADD, sockfd, &ev); int nOfEvent = 0; char *ipStr; int clientFd; int n; char line[256]; std::unordered_map<int, clientStruct> m; while(1) { nOfEvent = epoll_wait(epfd, events, 10, -1); for(int i = 0;i<nOfEvent;++i) { if(events[i].data.fd == sockfd) { clientStruct clientTemp; connfd = accept(sockfd, (sockaddr* )&client_addr, (socklen_t*)&addrlen); if(connfd<0) { printf("Error: Accept Failure!\n"); exit(1); } ipStr = inet_ntoa(client_addr.sin_addr); printf("client: %s\n", ipStr); clientTemp.ipAdd = ipStr; clientTemp.port = ntohs(client_addr.sin_port); m.insert(std::pair<int, clientStruct>(connfd, clientTemp)); ev.data.fd = connfd; ev.events = EPOLLIN|EPOLLET; epoll_ctl(epfd, EPOLL_CTL_ADD, connfd, &ev); } else if (events[i].events & EPOLLIN) { printf("EPOLLIN!\n"); if((clientFd = events[i].data.fd)<0)continue; if((n = read(clientFd, line, 256))<=0) { close(clientFd); printf("Client Error!\n"); m.erase(connfd); } else { line[n-1] = '!'; line[n] = 0; printf("Got message from: %s:", m.count(connfd)>0?m[connfd].ipAdd:"Unkown Client"); printf("%4d\n", m.count(connfd)>0?m[connfd].port:0); printf("data length = %d\n", strlen(line)); write(clientFd, line, strlen(line)+1); memset(line, 0, sizeof(line)); }
ev.data.fd = clientFd; ev.events = EPOLLIN|EPOLLET; }
} } close(sockfd); exit(EXIT_SUCCESS); }
|