1. 程式人生 > >linux c++select多人聊天程式

linux c++select多人聊天程式

比較簡單的多人聊天程式,可直接執行。

主要是實現功能。沒有介面也沒有多餘功能,只是實現群聊天的功能。c/s模式。

server端用select多路複用來做,可以接受多個客戶端連線。client端啟動2個執行緒控制傳送和接受資料。

==================================================================================================

server.h

#include <unistd.h>
#include <stdio.h>
#include <netinet/in.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <stdlib.h>
#include <arpa/inet.h>
int init(struct sockaddr_in addr)
{
    int sock;
    int ret;// 記錄錯誤馬
    sock=socket(AF_INET,SOCK_STREAM,0);
    if(sock==-1)return -1;
    ret=bind(sock,(struct sockaddr*)&addr,sizeof(addr));
    if(ret==-1)return -1;
    listen(sock,10);
    return sock;
}
int Link(int sock)
{
    int ret;//返回值
    int Maxfd;//最大描述符號
    int acpsock;//accpet函式返回值
    struct sockaddr_in acpaddr;//accpet用到的地址
    socklen_t len;//地址大小
    char buf[20];//接受到的訊息內容
    int resock;//recv中用到的檔案麼描述符號、
    int client[10];//儲存連線的檔案描述符
    int i,j;//for迴圈變數
    fd_set refd,allfd;


    for(i=0;i<10;i++)
    client[i]=-1;
    FD_ZERO(&refd);
    FD_ZERO(&allfd);
    Maxfd=sock;
    FD_SET(sock,&allfd);
    while(1)
{
   refd=allfd;
   ret=select(Maxfd+1,&refd,0,0,0);
   if(ret==-1)return -1;
   if(FD_ISSET(sock,&refd))
   {
     printf("someone connect\n");
     len=sizeof(acpaddr);
     acpsock=accept(sock,(struct sockaddr*) &acpaddr,&len);
     j=0;
     while(j<10 && client[j]!=-1)++j;
     client[j]=acpsock;
     Maxfd=Maxfd>acpsock?Maxfd:acpsock;
     FD_SET(acpsock,&allfd);
   }

   for(i=0;i<10;i++)
   {
if((resock=client[i])<0)continue;
    if(FD_ISSET(resock,&refd))
    {
      if((j=recv(resock,buf,20,0))==0)
           {
             printf("someone exit\n");
         close(resock);
     FD_CLR(resock,&allfd);
   client[i]=-1;
      }
   
   
  else
  {
       printf("%s",buf);
       for(i=0;i<10;i++)
       {
           if(client[i]!=resock)
       {
           //printf("%d ,",client[i]);
           send(client[i],buf,j,0);
}
       }
   }
    }
   }


}


return 0;
}
=====================================================================
server.cpp


#include "server.h"
#define SERVER_PORT 8888
int main()
{
    int Sock;
    struct sockaddr_in servaddr;


    servaddr.sin_family      = AF_INET;
    servaddr.sin_addr.s_addr = inet_addr("127.0.0.1");//htonl(INADDR_ANY);
    servaddr.sin_port        = htons(SERVER_PORT); 


    Sock=init(servaddr);
    if(-1==Sock)
    {
        printf("init error\n");
return -1;
    }
    printf("初始化成功\n");
    Link(Sock);   


    return 0;
}

============================

client端啟動2個執行緒用於讀和寫

client.h

#ifndef _CLENT_H_
#define _CLENT_H_
#include <unistd.h>
#include <stdlib.h>
#include <sys/socket.h>
#include <stdio.h>
#include <string.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <iostream>
using namespace std;
int init( struct sockaddr_in addr)
{
    int sock;
    int ret;
    sock=socket(AF_INET,SOCK_STREAM,0);
    ret=connect(sock,(struct sockaddr*)&addr,sizeof(addr));
    if(ret==-1)printf("connect erro\n");
    return sock;
}
int Chat(int sock)
{
//啟動兩個執行緒進行讀寫
    fd_set refd;
    int Maxfd;
char talk[20];
int ret;


    Maxfd=sock;
while(1)
    {
        FD_ZERO(&refd);
  FD_SET(0,&refd);
  FD_SET(sock,&refd);
        ret=select(Maxfd+1,&refd,0,0,0);
if (ret==-1)break;
if(FD_ISSET(0,&refd))
{
//scanf("%s",talk);
memset(talk,0,20);
fgets(talk,20,stdin);
send(sock,talk,strlen(talk)+1,0);
}
else if(FD_ISSET(sock,&refd))
{
   memset(talk,0,20);
            recv(sock,talk,20,0);
printf("%s",talk);
}
    }


}
void * ForRead(void *arg)
{
    char talk[20];
int* sock;
sock=(int*)arg;
while(1)
{
         memset(talk,0,20);
       fgets(talk,20,stdin);
       send(*sock,talk,strlen(talk)+1,0);
}
}
void * ForWrite(void *arg)
{
    char talk[20];
int *sock=(int *)arg;
while(1)
{
          memset(talk,0,20);
        recv(*sock,talk,20,0);
        cout<<talk;
}
}


#endif

====================================================================================================

client.cpp

#include "client.h"
int main()
{
pthread_t rid,wid;
    int sock,ret;
    struct sockaddr_in client_addr;
    client_addr.sin_family  = AF_INET;
    client_addr.sin_port    = htons(8888);
    //client_addr1.sin_addr.s_addr = inet_addr("127.0.0,1");
    inet_pton(AF_INET, "127.0.0.1", &client_addr.sin_addr);
    
    sock=init(client_addr);
   // Chat(sock);


pthread_create(&rid,0,ForRead,&sock);
   
   pthread_create(&wid,0,ForWrite,&sock);
pthread_join(rid,0);
pthread_join(wid,0);


    return 0;
}