服务器端代码
/*
*=====================================================================================
*
* 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下已经编译通过
基于流模式长连接的简单实现
最新推荐文章于 2021-12-22 15:35:18 发布