// Server side implementation of UDP client-server model
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/select.h>
#include <arpa/inet.h>
#include <netinet/in.h>
#include <sys/epoll.h>
#define MAXLINE 1024
#include <thread>
// Driver code
#define n_ports 3
int ports []= {8080,8081,8082};
void select_server() {
char buffer[MAXLINE];
struct sockaddr_in cliaddr;
memset(&cliaddr, 0, sizeof(cliaddr));
int sockfds[n_ports];
socklen_t len= sizeof(cliaddr);
int n;
fd_set readset;
int max_fd=0;
for(int i =0 ;i<n_ports;++i){
int sockfd;
struct sockaddr_in servaddr;
memset(&servaddr, 0, sizeof(servaddr));
// Filling server information
servaddr.sin_family = AF_INET; // IPv4
servaddr.sin_addr.s_addr = INADDR_ANY;
servaddr.sin_port = htons(ports[i]);
// Creating socket file descriptor
if ( (sockfd = socket(AF_INET, SOCK_DGRAM, 0)) < 0 ) {
perror("socket creation failed");
exit(EXIT_FAILURE);
}
// Bind the socket with the server address
if ( bind(sockfd, (const struct sockaddr *)&servaddr,sizeof(servaddr)) < 0 )
{
perror("bind failed");
exit(EXIT_FAILURE);
}
sockfds[i] = sockfd;
max_fd = (sockfd>max_fd)?sockfd:max_fd;
}
printf("server begin\n");
while(true){
FD_ZERO(&readset);
for(int i=0;i<n_ports;++i)
FD_SET(sockfds[i],&readset);
int ret = select(max_fd+1,&readset,NULL,NULL,NULL);
if (ret == -1){
printf("error");
continue;
}
else{
for(int i=0;i<n_ports;++i)
if (FD_ISSET(sockfds[i],&readset)){
n = recvfrom(sockfds[i], (char *)buffer, MAXLINE,
MSG_WAITALL, ( struct sockaddr *) &cliaddr,&len);
buffer[n] = '\0';
printf("Server recive : %s\n", buffer);
}
}
}
}
void epoll_server(){
char buffer[MAXLINE];
struct sockaddr_in cliaddr;
socklen_t len= sizeof(cliaddr);
memset(&cliaddr, 0, sizeof(cliaddr));
struct epoll_event epoll_events[n_ports];
int n;
int epollfd = epoll_create(1024);
for(int i =0 ;i<n_ports;++i){
int sockfd;
struct sockaddr_in servaddr;
memset(&servaddr, 0, sizeof(servaddr));
// Filling server information
servaddr.sin_family = AF_INET; // IPv4
servaddr.sin_addr.s_addr = INADDR_ANY;
servaddr.sin_port = htons(ports[i]);
// Creating socket file descriptor
if ( (sockfd = socket(AF_INET, SOCK_DGRAM, 0)) < 0 ) {
perror("socket creation failed");
exit(EXIT_FAILURE);
}
// Bind the socket with the server address
if ( bind(sockfd, (const struct sockaddr *)&servaddr,sizeof(servaddr)) < 0 )
{
perror("bind failed");
exit(EXIT_FAILURE);
}
epoll_events[i].events = EPOLLIN;
epoll_events[i].data.fd = sockfd;
epoll_ctl(epollfd,EPOLL_CTL_ADD,sockfd,&epoll_events[i]);
}
struct epoll_event events_in[n_ports];
while (true){
int event_count = epoll_wait(epollfd,events_in,16,-1);
for(int i=0;i<event_count;++i){
if(events_in[i].events &EPOLLIN){
int new_fd = events_in[i].data.fd;
n = recvfrom(new_fd, (char *)buffer, MAXLINE,
MSG_WAITALL, ( struct sockaddr *) &cliaddr,&len);
buffer[n] = '\0';
printf("Server recive : %s\n", buffer);
}
}
}
}
void client(int port) {
int sockfd;
struct sockaddr_in servaddr;
memset(&servaddr, 0, sizeof(servaddr));
// Filling server information
servaddr.sin_family = AF_INET;
servaddr.sin_port = htons(port);
servaddr.sin_addr.s_addr = INADDR_ANY;
// Creating socket file descriptor
if ( (sockfd = socket(AF_INET, SOCK_DGRAM, 0)) < 0 ) {
perror("socket creation failed");
exit(EXIT_FAILURE);
}
char write_buf[1024];
for(int i=0;i<1000;++i){
sprintf(write_buf,"Client:%d say %d",port,i);
printf("%s\n",write_buf);
sendto(sockfd, write_buf, strlen(write_buf),
MSG_CONFIRM, (const struct sockaddr *) &servaddr,
sizeof(servaddr));
sleep(1);
}
close(sockfd);
}
int main(){
//std::thread ta(select_server);
std::thread ta(epoll_server);
std::thread tb(client,8080);
std::thread tc(client,8081);
std::thread td(client,8082);
ta.join();
tb.join();
tc.join();
td.join();
return 0;
}