基于Select模型的匿名聊天室v10
最近在无聊完成了一个简单的基于select模型的匿名聊天室程序,均使用C++开发
服务器工作原理:
每接收一条客户端的信息,就将遍历所有的socket,并将该信息发给所有的客户端.
客户端使用两条线程,一个是接收服务端信息的线程,一个是等待阻塞输入的线程,获得输入时,将输入发送到服务器。
项目源码:https://github.com/coderguang/Chat
版本为v2.0的release.
其中ComLib也在github上
服务器核心代码:
int main(int argc,char **argv){
int i,counter,maxfd,sockfd,listenfd,connfd;
int nready,client[FD_SETSIZE];
ssize_t n;
fd_set rset,allset;
char buf[MSGSIZE];
socklen_t clilen;
struct sockaddr_in cliaddr;
struct sockaddr_in servaddr;
listenfd=Socket(AF_INET,SOCK_STREAM,0);
bzero(&servaddr,sizeof(servaddr));
servaddr.sin_family=AF_INET;
servaddr.sin_port=htons(PORT);
//servaddr.sin_port=htons(atoi(argv[0]));
servaddr.sin_addr.s_addr=INADDR_ANY;
Bind(listenfd,(struct sockaddr*)&servaddr,sizeof(servaddr));
Listen(listenfd,10);
maxfd=listenfd; //initialize
counter=-1;
for(i=0;i<FD_SETSIZE;i++){
client[i]=-1;
}
FD_ZERO(&allset);
FD_SET(listenfd,&allset);
for(;;){
rset=allset;
nready=Select(maxfd+1,&rset,NULL,NULL,NULL);
if(FD_ISSET(listenfd,&rset)){//new client connecton
clilen=sizeof(cliaddr);
connfd=Accept(listenfd,(struct sockaddr *)&cliaddr,&clilen);
for(i=0;i<FD_SETSIZE;i++){
if(client[i]<0){
client[i]=connfd;//save the new sockfd
break;
}
}
if(i==FD_SETSIZE){
cout<<”sockfd set full!”<<endl;
}
FD_SET(connfd,&allset);//add new to set
if(connfd>maxfd){
maxfd=connfd;//for select
}
if(i>counter){//max index in client[]
counter=i;
}
if(nready<=0){
continue; //no more readable
}
}
for(i=0;i<FD_SETSIZE;i++){//check all clients for data
if((sockfd=client[i])<0){
continue;
}
if(FD_ISSET(sockfd,&rset)){
memset(buf,sizeof(buf),’\0’);
if((n=Read(sockfd,buf,MSGSIZE))==0){
close(sockfd);//connection closed by client
FD_CLR(sockfd,&allset);
client[i]=-1;
}else{
buf[n]=’\0’;
cout<<”get the msg:”<<buf<<endl;
for(int j=0;j<FD_SETSIZE;j++){
if(client[j]!=-1)
Writen(client[j],buf,n);
}
}
if(nready<=0){
break;
}
}
}
}
}
客户端核心代码:
int main(){
WORD mVersionRequested;
WSADATA wsaData;//WSADATA结构被用来保存AfxSocketInit函数返回的WindowsSockets初始化信息。
int ret;
SOCKET sClient;
struct sockaddr\_in saServer;
bool fSuccess=true;
//winSock 初始化
mVersionRequested=MAKEWORD(2,2);//WinSock dll的版本
ret=WSAStartup(mVersionRequested,&wsaData);
if(ret!=0){
cout<<"WSASartup failed!"<<endl;
getchar();
getchar();
exit(1);
}
if(LOBYTE(wsaData.wVersion)!=2HIBYTE(wsaData.wVersion)!=2){
WSACleanup();
cout<<"invaild version"<<endl;
getchar();
getchar();
exit(1);
}
sClient = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
if (sClient == INVALID_SOCKET){
WSACleanup();
cout << “socket failed” << endl;
getchar();
getchar();
exit(0);
}
saServer.sin\_family=AF\_INET;
saServer.sin\_port=htons(port);
saServer.sin\_addr.S\_un.S\_addr=inet\_addr(host);
ret=connect(sClient,(struct sockaddr \*)&saServer,sizeof(saServer));
if(ret==SOCKET\_ERROR){
cout<<"连接失败!"<<endl;
closesocket(sClient);
WSACleanup();
getchar();
getchar();
exit(1);
}
thread recThread(Receive, sClient);
thread sendThread(ChatInput,sClient);
recThread.join();
sendThread.join();
cout << “over” << endl;
closesocket(sClient);
WSACleanup();
getchar();
getchar();
return 0;
}
重新找工作以来,投了第一家,昨天去面了,9377,感觉还不错,不过感觉自己要价太高了~~~
一个应届生,没有服务端的工作经验,只有半年的U3D实习经验,要8K确实过了,还是太年轻,经验太少啊,其实8K只是期望,低点也是无所谓的,6K5我就接受啦下午三点笔试面试一直面到了总经理面,到了6点他们总经理还没有空,HR说等他们确定了之后再约,这个确定是神马意思~~~,看来要多投几份了~~~,不过还是挺喜欢9377的,离我现在住的走路地方只要5分钟路程~~~
do hard~~
—————————————————————————————————————————————————————————————————
//写的错误或者不好的地方请多多指导,可以在下面留言或者点击左上方邮件地址给我发邮件,指出我的错误以及不足,以便我修改,更好的分享给大家,谢谢。
转载请注明出处:http://blog.csdn.net/qq844352155
author:天下无双
Email:royalchen@royalchen.com
2015-6-30
于广州天河荷光路
——————————————————————————————————————————————————————————————————
- 本文作者: royalchen
- 本文链接: http://www.royalchen.com/2016/02/24/基于select模型的匿名聊天室v10/
- 版权声明: 本博客所有文章除特别声明外,均采用 MIT 许可协议。转载请注明出处!