天下

记录修行的印记

linux Socket多路复用模式服务端 69.cpp

// 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);
}

posted on 2011-09-08 16:03 天下 阅读(325) 评论(0)  编辑 收藏 引用 所属分类: SocketLinux编程


只有注册用户登录后才能发表评论。
【推荐】超50万行VC++源码: 大型组态工控、电力仿真CAD与GIS源码库
网站导航: 博客园   IT新闻   BlogJava   知识库   博问   管理


<2011年9月>
28293031123
45678910
11121314151617
18192021222324
2526272829301
2345678

导航

统计

常用链接

留言簿(3)

随笔分类(369)

随笔档案(320)

链接

最新随笔

搜索

最新评论