// File: 69.cpp
#include <iostream>
#include <map>
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <math.h>
#include <string.h>
#include <strings.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <bitset>
using namespace std;
#define PORT 1234 /* Port that will be opened */
#define BACKLOG 5 /* Number of allowed connections */
#define MAXDATASIZE 4096
typedef map<unsigned int,sockaddr_in> connects;
void process_cli(int sockfd,sockaddr_in addr,char* recvbuf, int len);
void reverser(char* szIn,char* szOut,unsigned int nLen)
{
for (int i=0;i<nLen;i++) {
szOut[i] = szIn[nLen-i-1];
}
}
int main()
{
connects connect_fds;
int sock_fd;
ssize_t recv_size;
fd_set read_set;
fd_set all_set;
int listen_fd;
int connect_fd;
int ready_size;
socklen_t addr_size;
sockaddr_in srv_addr;
sockaddr_in addr;
unsigned int max_fd = 0;
char recv_buf[MAXDATASIZE];
if ((listen_fd = socket(AF_INET, SOCK_STREAM, 0)) == -1) {
perror("Creating socket failed.");
exit(1);
}
int opt = SO_REUSEADDR;
setsockopt(listen_fd, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt));
bzero(&srv_addr,sizeof(srv_addr));
srv_addr.sin_family=AF_INET;
srv_addr.sin_port=htons(PORT);
srv_addr.sin_addr.s_addr = htonl (INADDR_ANY);
if (bind(listen_fd, (struct sockaddr *)&srv_addr, sizeof(struct sockaddr)) == -1) {
perror("Bind error.");
exit(1);
}
if(listen(listen_fd,BACKLOG) == -1) {
perror("listen() error\n");
exit(1);
}
max_fd = listen_fd;
addr_size=sizeof(sockaddr_in);
FD_ZERO(&all_set);
FD_SET(listen_fd, &all_set);
connects::iterator iter;
printf("clients:(%u) ,current listen socket:%u\n",connect_fds.size(),listen_fd);
while(1)
{
read_set = all_set;
ready_size = select(max_fd+1, &read_set, NULL, NULL, NULL);
if ( FD_ISSET(listen_fd,&read_set) ) {
connect_fd = accept(listen_fd,(struct sockaddr *)&addr,&addr_size);
if (connect_fd ==-1 ) {
perror("accept() error\n");
continue;
}
connect_fds[connect_fd] = addr;
max_fd = connect_fd;
FD_SET(connect_fd, &all_set);
printf("clients:(%u) ,%s:%d connected ,connect socket:%u\n",connect_fds.size(),inet_ntoa(addr.sin_addr),ntohs(addr.sin_port),connect_fd);
}
for ( iter = connect_fds.begin(); iter!=connect_fds.end(); iter++) {
sock_fd = iter->first;
addr = iter->second;
if ( FD_ISSET(sock_fd,&read_set) ) {
recv_size = recv(sock_fd, recv_buf, MAXDATASIZE,0);
if ( recv_size == 0) {
close(sock_fd);
FD_CLR(sock_fd, &all_set);
connect_fds.erase(sock_fd);
printf("%s:%d disconnected\n",inet_ntoa(addr.sin_addr),ntohs(addr.sin_port) );
}
else {
process_cli(sock_fd,addr,recv_buf,recv_size);
}
}
}
}
close(listen_fd);
}
void process_cli(int sockfd,sockaddr_in addr,char* recvbuf, int len)
{
char sendbuf[MAXDATASIZE];
printf("Received %s:%d message: %s\n",inet_ntoa(addr.sin_addr),ntohs(addr.sin_port), recvbuf);
reverser(recvbuf,sendbuf,len);
printf("Send To %s:%d message: %s\n",inet_ntoa(addr.sin_addr),ntohs(addr.sin_port), sendbuf);
send(sockfd,sendbuf,len,0);
}