您的位置:首页 > 运维架构 > Linux

linux c++select多人聊天程序

2013-02-01 15:35 239 查看
比较简单的多人聊天程序,可直接运行。

主要是实现功能。没有界面也没有多余功能,只是实现群聊天的功能。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;

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: