linux 下用c语言编写的聊天室程序服务器和客户端.docx

上传人:b****6 文档编号:5382917 上传时间:2022-12-15 格式:DOCX 页数:19 大小:19.69KB
下载 相关 举报
linux 下用c语言编写的聊天室程序服务器和客户端.docx_第1页
第1页 / 共19页
linux 下用c语言编写的聊天室程序服务器和客户端.docx_第2页
第2页 / 共19页
linux 下用c语言编写的聊天室程序服务器和客户端.docx_第3页
第3页 / 共19页
linux 下用c语言编写的聊天室程序服务器和客户端.docx_第4页
第4页 / 共19页
linux 下用c语言编写的聊天室程序服务器和客户端.docx_第5页
第5页 / 共19页
点击查看更多>>
下载资源
资源描述

linux 下用c语言编写的聊天室程序服务器和客户端.docx

《linux 下用c语言编写的聊天室程序服务器和客户端.docx》由会员分享,可在线阅读,更多相关《linux 下用c语言编写的聊天室程序服务器和客户端.docx(19页珍藏版)》请在冰豆网上搜索。

linux 下用c语言编写的聊天室程序服务器和客户端.docx

linux下用c语言编写的聊天室程序服务器和客户端

/*

*server.c

*

*Createdon:

2012-6-15

*Author:

root

*/

#include

#include

#include

#include

#include

#include

#include

#include

#include

#definePORT7999

#defineMAX_NUM3//client连接最大个数

#defineMAX_CLIENT15

#defineMAX_SIZE1024

pthread_rwlock_tidx_lock,wait_lock;

//client信息

typedefstruct_client{

intsockfd;

charname[20];

pthread_tpid;

intflg;

}c_client;

c_clientclient[MAX_CLIENT];//定义client;

//等待的client

struct_client_{

intsockfd;

charname[20];

pthread_tpid;

struct_client_*next;

};

typedefstruct_client_c_client_c;

c_client_c*head=NULL;

c_client_c*temp_c1=NULL,*temp_c2=NULL;//等待的

//初始化client信息

voidinit_client(){

inti=0;

for(i=0;i

client[i].sockfd=-1;

memset(client[i].name,0,20);

client[i].pid=-1;

client[i].flg=-1;

}

}

//查找结构体数组中sockfd为-1的下标值

intfind_fd(c_client*client){

inti=0;

while(i

//printf("====%d\n",client[i].sockfd);

if(client[i].sockfd==-1)

returni;

i++;

}

return-1;

}

//判断登录格式

intlogform(char*buf){

char*p=strstr(buf,"LOGIN\r\n");

intn=strlen(buf);

char*q=p+n-4;

if(p!

=NULL&&p+7!

=q&&strcmp(q,"\r\n\r\n")==0)

return1;

else

return0;

}

intcmpname(char*buf,c_client*p_client){

inti=0;

char*p=strtok(buf+7,"\r\n\r\n");

while(client[i].sockfd!

=-1&&client[i].sockfd!

=p_client->sockfd&&i

if(strcmp(client[i].name,p)==0)

return0;

i++;

}

return1;

}

//SHOW

voidshowuser(c_client*p_client){

inti=0;

charbuf[1024]={0};

strcpy(buf,"200\r\n");

for(i=0;i

if(client[i].sockfd!

=-1){

sprintf(buf+strlen(buf),"%s\r\n",client[i].name);

}

}

sprintf(buf+strlen(buf),"\r\n");

send(p_client->sockfd,buf,strlen(buf),0);

}

//ALL

voidsendto_all(c_client*p_client,char*buf){

inti=0;

charsendbuf[1024]={0};

sprintf(sendbuf,"AFROM\r\n%s\r\n%s",p_client->name,buf+5);

for(i=0;i

if(client[i].sockfd!

=-1&&client[i].flg!

=-1)

if(send(client[i].sockfd,sendbuf,strlen(sendbuf),0)<=0){

printf("senderrrrrr\n");

exit

(1);

}

}

}

intfindname(char*name){

inti=0;

for(i=0;i

if(client[i].sockfd!

=-1&&strcmp(client[i].name,name)==0)

returnclient[i].sockfd;

}

return0;

}

//TO

voidsendto_one(c_client*p_client,char*buf){

inti=0;

charsendbuf[1024]={0};

charname[20]={0};

char*p=strtok(buf+4,"\r\n");//TO\r\n:

4个字符后取出\r\n前的名字

strcpy(name,p);

intsock=findname(name);

if(!

sock){

sprintf(sendbuf,"ERROR2\r\n%s用户不存在\r\n\r\n",name);

send(p_client->sockfd,sendbuf,strlen(sendbuf),0);

}else{

sprintf(sendbuf,"FROM\r\n%s\r\n%s",p_client->name,buf+4+strlen(

name)+2);

if(send(sock,sendbuf,strlen(sendbuf),0)<=0){

printf("senderrrrrr\n");

exit

(1);

}

}

}

voidpthread_fun(void*cclient);

//quit

voidquit(c_client*p_client){

inti=0;

intidx;

charbuf[1024]={0};

c_client_c*temp;

printf("--%s退出聊天室\n",p_client->name);

close(p_client->sockfd);

p_client->sockfd=-1;

p_client->pid=-1;

p_client->flg=-1;

sprintf(buf,"NOTICE1\r\n%s退出聊天室\r\n\r\n",p_client->name);

memset(p_client->name,0,20);

for(i=0;i

if(client[i].sockfd!

=-1&&client[i].flg!

=-1)

send(client[i].sockfd,buf,strlen(buf),0);

}

if(head!

=NULL&&head->next!

=NULL){

memset(buf,0,1024);

pthread_rwlock_rdlock(&idx_lock);

idx=find_fd(client);

pthread_rwlock_unlock(&idx_lock);

client[idx].sockfd=head->next->sockfd;

pthread_rwlock_wrlock(&wait_lock);

temp=head->next;

head->next=head->next->next;

free(temp);

pthread_rwlock_unlock(&wait_lock);

sprintf(buf,"NOTICE\r\n您已被唤醒,请继续操作\r\n\r\n");

send(client[idx].sockfd,buf,strlen(buf),0);

if(pthread_create(&client[idx].pid,NULL,(void*)pthread_fun,(void*)&client[idx])!

=0){

perror("pthread_create");

exit

(1);

}

pthread_detach(client[idx].pid);

}

}

voidpthread_fun(void*cclient){

c_client*p_client=(c_client*)cclient;

charbuf[MAX_SIZE]={0};

charsendbuf[1024]={0};

inti,n;

char*p;

sprintf(sendbuf,"%s","NOTICE\r\n通讯通道开启\r\n\r\n");

if(send(p_client->sockfd,sendbuf,strlen(sendbuf),0)<=0){

printf("senderr\n");

}

memset(sendbuf,0,1024);

while

(1){

memset(buf,0,MAX_SIZE);

n=recv(p_client->sockfd,buf,sizeof(buf)-1,MSG_NOSIGNAL);

if(n<=0){

close(p_client->sockfd);

p_client->sockfd=-1;

break;

}

if(logform(buf)){

if(cmpname(buf,p_client)==0){

send(p_client->sockfd,"ERROR\r\n用户名重复\r\n\r\n",26,0);

continue;

}else{

p_client->flg=1;

p=strtok(buf+7,"\r\n\r\n");

strcpy(p_client->name,p);

sprintf(sendbuf,"100\r\n%s\r\n\r\n",p_client->name);

send(p_client->sockfd,sendbuf,sizeof(sendbuf),0);

printf("%s进入聊天室\n",p_client->name);

for(i=0;i

if(client[i].sockfd!

=-1&&client[i].sockfd

!

=p_client->sockfd&&client[i].flg!

=-1)

send(client[i].sockfd,sendbuf,sizeof(sendbuf),0);

}

memset(sendbuf,0,1024);

while

(1){

memset(buf,0,MAX_SIZE);

if((n=recv(p_client->sockfd,buf,MAX_SIZE,0))<=0){

perror("recverr");

break;

}

//printf("recv=%s\n",buf);

if((p=strstr(buf,"\r\n\r\n"))!

=NULL&&*(p+4)

=='\0'){

if(!

strncmp(buf,"SHOW\r\n\r\n",8)){

showuser(p_client);//客户端执行show后,发送给客户端已连接的用户

continue;

}

if(!

strncmp(buf,"ALL\r\n",5)){

sendto_all(p_client,buf);

continue;

}

if(!

strncmp(buf,"TO\r\n",4)){

sendto_one(p_client,buf);

continue;

}

if(!

strncmp(buf,"QUIT\r\n\r\n",8))

quit(p_client);

//break;

pthread_exit(NULL);

}else{

send(p_client->sockfd,"ERROR\r\n信息不符合协议要求\r\n\r\n",

38,0);

}

}

}

}else{

send(p_client->sockfd,"ERROR\r\n未登录,请您登录再进行其他操作\r\n\r\n",56,0);

}

}

pthread_exit(NULL);

}

intmain(){

intser_sockfd,clt_sockfd;

structsockaddr_inaddr;

intidx;

charbuf[1024]={0};

//pthread_rwlock_tidx_lock,wait_lock;

pthread_rwlock_init(&idx_lock,NULL);

pthread_rwlock_init(&wait_lock,NULL);

init_client();

//创建服务器sockfd

if((ser_sockfd=socket(AF_INET,SOCK_STREAM,0))==-1){

perror("socket");

exit

(1);

}

//设置服务器网络地址

bzero(&addr,sizeof(addr));

addr.sin_family=AF_INET;

addr.sin_port=htons(PORT);

addr.sin_addr.s_addr=htonl(INADDR_ANY);

//设置端口可重用

intopt=1;

setsockopt(ser_sockfd,SOL_SOCKET,SO_REUSEADDR,&opt,sizeof(opt));

//将套接字绑定到服务器的网络地址上

if(bind(ser_sockfd,(structsockaddr*)&addr,sizeof(addr))==-1){

perror("bind");

exit

(1);

}

printf("bindsuccess\n");

//监听连接请求--监听队列长度为10

if(listen(ser_sockfd,10)==-1){

perror("listen");

exit

(1);

}

printf("listensuccess\n");

while

(1){

if((clt_sockfd=accept(ser_sockfd,NULL,NULL))==-1){

perror("accept");

exit

(1);

}

pthread_rwlock_rdlock(&idx_lock);

idx=find_fd(client);

//printf("idx=%d\n",idx);

pthread_rwlock_unlock(&idx_lock);

if(idx!

=-1){//连接末满

client[idx].sockfd=clt_sockfd;

if(pthread_create(&client[idx].pid,NULL,(void*)pthread_fun,

(void*)&client[idx])!

=0){

perror("pthread_create");

exit

(1);

}

pthread_detach(client[idx].pid);

}else{//连接已满,等待

temp_c1=(c_client_c*)malloc(sizeof(c_client_c));

temp_c1->sockfd=clt_sockfd;

temp_c1->next=NULL;

pthread_rwlock_wrlock(&wait_lock);

if(head==NULL){

head=(c_client_c*)malloc(sizeof(c_client_c));

head->next=temp_c1;

}else{

for(temp_c2=head;temp_c2->next!

=NULL;temp_c2=temp_c2->next);

temp_c2->next=temp_c1;

}

pthread_rwlock_unlock(&wait_lock);

memset(buf,0,1024);

sprintf(buf,"NOTICE\r\n服务器已满,请等候\r\n\r\n");//客户端接受则等待

if(send(temp_c1->sockfd,buf,strlen(buf),0)<=0){

printf("sendrerr\n");

}

}

}

}

/*

*client.c

*

*Createdon:

2012-6-18

*Author:

root

*/

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#defineMAX_SIZE1024

#definePORT7999

staticintFLAGE=-1;

charname[20]={0};

voidfun_show(intsockfd){

charsendbuf[256]={0};

sprintf(sendbuf,"SHOW\r\n\r\n");

if(send(sockfd,sendbuf,strlen(sendbuf),0)<=0){

printf("senderr\n");

close(sockfd);

exit

(1);

}

}

voidfun_all(intsockfd){

charsendbuf[MAX_SIZE]={0};

sprintf(sendbuf,"ALL\r\n",5);

printf("输入发送的内容:

\n");

scanf("%s",sendbuf+5);

sprintf(sendbuf+strlen(sendbuf),"\r\n\r\n");

if(send(sockfd,sendbuf,strlen(sendbuf),0)<=0){

printf("senderr\n");

close(sockfd);

exit

(1);

}

}

voidfun_one(intsockfd){

charsendbuf[MAX_SIZE]={0};

charname3[20]={0};

printf("输入聊天对象:

");

scanf("%s",name3);

sprintf(sendbuf,"TO\r\n%s\r\n",name3);

printf("输入聊天内容:

\n");

scanf("%s",sendbuf+strlen(sendbuf));

sprintf(sendbuf+strlen(sendbuf),"\r\n\r\n");

if(send(sockfd,sendbuf,strlen(sendbuf),0)<=0){

printf("senderr\n");

close(sockfd);

exit

(1);

}

}

voidfun_quit(intsockfd){

charsendbuf[256]="QUIT\r\n\r\n";

if(send(sockfd,sendbuf,strlen(sendbuf),0)<=0){

printf("senderr\n");

close(sockfd);

exit

(1);

}

}

void*pthread_fun(int*sock){

intsockfd

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 人文社科 > 文化宗教

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1