基于Select模型的匿名聊天室v1.0

来源:互联网 发布:db2客户端连接数据库 编辑:程序博客网 时间:2024/05/17 03:49

最近在无聊完成了一个简单的基于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; //initializecounter=-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 connectonclilen=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 sockfdbreak;}}if(i==FD_SETSIZE){cout<<"sockfd set full!"<<endl;}FD_SET(connfd,&allset);//add new to setif(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 dataif((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 clientFD_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;}}}}}

客户端核心代码:

<span style="font-size:18px;">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)!=2||HIBYTE(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;}</span>


重新找工作以来,投了第一家,昨天去面了,9377,感觉还不错,不过感觉自己要价太高了~~~

一个应届生,没有服务端的工作经验,只有半年的U3D实习经验,要8K确实过了,还是太年轻,经验太少啊~~,其实8K只是期望,低点也是无所谓的,6K5我就接受啦~~下午三点笔试面试一直面到了总经理面,到了6点他们总经理还没有空,HR说等他们确定了之后再约,这个确定是神马意思~~~,看来要多投几份了~~~,不过还是挺喜欢9377的,离我现在住的走路地方只要5分钟路程~~~


do hard~~


—————————————————————————————————————————————————————————————————

//写的错误或者不好的地方请多多指导,可以在下面留言或者点击左上方邮件地址给我发邮件,指出我的错误以及不足,以便我修改,更好的分享给大家,谢谢。

转载请注明出处:http://blog.csdn.net/qq844352155

author:天下无双

Email:royalchen@royalchen.com

2015-6-30

于广州天河荷光路

——————————————————————————————————————————————————————————————————



  



0 0
原创粉丝点击