`
sogo6
  • 浏览: 110318 次
  • 性别: Icon_minigender_1
  • 来自: 深圳
社区版块
存档分类
最新评论

基于流模式长连接的简单实现

阅读更多
服务器端代码

/*
*=====================================================================================
*
*   Filename: server.cc
*  Description: 
*    Version: 1.0
*    Created: 2008年12月18日09时50分50秒CST
*   Revision: none*
*    Author: ugg(ugg_xchj@yahoo.com.cn)
*    Company: 
*
*=====================================================================================
*/
#include<string>
#include<iostream>
#include<netdb.h>
#include<sys/socket.h>
#include<sys/types.h>
#include<netinet/in.h>
#include<arpa/inet.h>
#include<errno.h>
#include<map>
usingnamespace::std;
structclientInfo
{
  stringhost;
  intport;
};
typedefmap<int,clientInfo>mapgroups;
typedefmap<int,clientInfo>::iteratormapgroupsor;
typedefmap<int,clientInfo>::const_iteratormapgroupscor;
// 记录客户端的信息
mapgroupsgroups;
//默认内容设置
stringhostname="localhost";
int  hostport=7763;
stringserversendContents="thisisserver";
voidgetCMD(intargc,char*argv[])
{
  switch(argc)
  {
    case2:
      hostname=argv[1];
     break;
    case3:
      hostname=argv[1];
      hostport=atoi(argv[2]);  
      if(hostport<1024||hostport>65535)
      {
        cerr<<"Error:port="<<hostport 
          <<"Error,range1024-65535"<<endl;
        exit(0);
      }
      break;
    case4:
      hostname=argv[1];
      hostport=atoi(argv[2]);  
      if(hostport<1024||hostport>65535)
      {
        cerr<<"Error:port="<<hostport 
          <<"Error,range1024-65535"<<endl;
        exit(0);
      }
      serversendContents=argv[3];  
      break;
    default:
      break;
  }
}  
voidclearfd(intfd,fd_set&rdfds)
{
  FD_CLR(fd,&rdfds); 
  mapgroupsorit=groups.find(fd);
  if(it!=groups.end())
  {
    cerr<<"clienthost="<<it->second.host<<",port="<<it->second.port 
      <<"close"<<endl;
    groups.erase(fd);
  }
}
//recvandsendmessage
voidrecvandsend(intfd,fd_set&rdfds,string&contents,conststring&texts)
{
  //接受消息
  charbuffer[1024];
  intrets=0;
  intret=0;
  ret=recv(fd,buffer,8,0);
  if(ret==0)
  {
    clearfd(fd,rdfds);
    return;
  }
  if(ret==8)
  {
    buffer[8]='';
    intlen=atoi(buffer);
    if(len<1024){
      while((ret=recv(fd,buffer,len,0))>0)
      {
        contents.append(buffer,ret);
        rets+=ret;
        len-=ret;
        if(len==0)
          break;
      }
      if(ret==0){
        clearfd(fd,rdfds);
        return;
      }
    }else{
      intbuflen=1024;
      while((ret=recv(fd,buffer,buflen,0))>0)
      {
        contents.append(buffer,ret);
        rets+=ret;
        len-=ret;
        if(len<2048){
          buflen=len;
        }
        if(len<=0)
          break;
      }
      if(ret==0){
        clearfd(fd,rdfds);
        return;
      }
    }
  }else{
    clearfd(fd,rdfds);
    return;
  }
  //发送信息
  sprintf(buffer,"%8d",texts.length());  
  stringsendContents=string(buffer,8);
  sendContents+=texts;
  constchar*content=sendContents.c_str();
  intsend=0;
  intlength=sendContents.length();
  //send
  while(1)
  {
    intret=write(fd,content+send,length-send);
    if(ret==0)
    {
      //serverclose
      cerr<<"Error:serverclose"<<endl;
      clearfd(fd,rdfds);
      return;
    }
    send+=ret;
    if(length==send)
      break;
  }
}  
int
main(intargc,char*argv[])
{
  getCMD(argc,argv);
  intfd; 
  //createsocket
  if((fd=socket(PF_INET,SOCK_STREAM,0))==-1)
  {
    cerr<<"Error:socket()"<<endl;
    exit(0);
  }
  // 
  structhostent*he;
  he=gethostbyname(hostname.c_str());
  if(he==NULL){
    cerr<<"Error:gethostbyname()error,hostname="<<hostname<<endl;
    exit(0);
  }
  structsockaddr_inserv_addr;
  serv_addr.sin_family=AF_INET;
  serv_addr.sin_port=htons(hostport);
  serv_addr.sin_addr=*((structin_addr*)he->h_addr);
  bzero(&(serv_addr.sin_zero),8);
  //bind
  if(bind(fd,(structsockaddr*)&serv_addr,sizeof(serv_addr))==-1){
    cerr<<"Error:bind()error"<<endl;
    exit(0);
  }
  //listen
  intret_listen=listen(fd,5);
  if(ret_listen<0)
  {
    cerr<<"Error:Listenporterror,socketfd:"<<fd<<endl;
    cerr<<"Error:listenerrno="<<ret_listen<<endl;
    exit(0);
  }
  fd_setrdfds;
  intnfds;
  //Firstpollthesockets
  FD_ZERO(&rdfds);
  FD_SET(fd,&rdfds);
  while(1)
  {
    if((nfds=select(FD_SETSIZE,&rdfds,NULL,NULL,NULL))<0){
      if(errno!=EINTR){
        cerr<<"Error:selecterror"<<endl;
        exit(3);
      }
    }
    if(FD_ISSET(fd,&rdfds))
    {
      socklen_tlen;
      structsockaddr_inclient_addr;
      len=sizeof(structsockaddr);
      intclientfd=accept(fd,(structsockaddr*)&client_addr,&len);
      if(clientfd==-1)
      {
        cerr<<"Error:acceptclienterror"<<endl;
      }else{
        clientInfoinfo;  
        info.host=inet_ntoa(client_addr.sin_addr);
        info.port=ntohs(client_addr.sin_port);
        cerr<<"server:gotconnectionfrom"<<info.host 
          <<",port"<<info.port<<endl;
        groups.insert(make_pair(clientfd,info));
        FD_SET(clientfd,&rdfds);
      }
    }else{
      mapgroupscorit;
      for(it=groups.begin();it!=groups.end();++it)
      {
        if(FD_ISSET(it->first,&rdfds))
        {
          stringstrRev;
          recvandsend(it->first,rdfds,strRev,serversendContents);     
          break;
        }
      }
    }
  }  
  return0;
}       /*---------- endoffunctionmain ----------*/

  上面的代码在linux下已经编译通过
分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics