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;
}


  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值