linux-下用c语言编写的聊天室程序-服务器和客户端(共14页).doc

上传人:飞****2 文档编号:16271214 上传时间:2022-05-16 格式:DOC 页数:16 大小:49KB
返回 下载 相关 举报
linux-下用c语言编写的聊天室程序-服务器和客户端(共14页).doc_第1页
第1页 / 共16页
linux-下用c语言编写的聊天室程序-服务器和客户端(共14页).doc_第2页
第2页 / 共16页
点击查看更多>>
资源描述

《linux-下用c语言编写的聊天室程序-服务器和客户端(共14页).doc》由会员分享,可在线阅读,更多相关《linux-下用c语言编写的聊天室程序-服务器和客户端(共14页).doc(16页珍藏版)》请在得力文库 - 分享文档赚钱的网站上搜索。

1、精选优质文档-倾情为你奉上/* * server.c * * Created on: 2012-6-15 * Author: root */#include #include #include #include #include #include #include #include #include#define PORT 7999#define MAX_NUM 3 /client连接最大个数#define MAX_CLIENT 15#define MAX_SIZE 1024pthread_rwlock_t idx_lock, wait_lock;/client 信息typedef struc

2、t _client int sockfd;char name20;pthread_t pid;int flg; c_client;c_client clientMAX_CLIENT;/定义client;/等待的clientstruct _client_ int sockfd;char name20;pthread_t pid;struct _client_ *next;typedef struct _client_ c_client_c;c_client_c *head = NULL;c_client_c *temp_c1 = NULL, *temp_c2 = NULL;/等待的/初始化cli

3、ent信息void init_client() int i = 0;for (i = 0; i MAX_CLIENT; i+) clienti.sockfd = -1;memset(clienti.name, 0, 20);clienti.pid = -1;clienti.flg = -1;/查找结构体数组中sockfd为-1的下标值int find_fd(c_client *client) int i = 0;while (i sockfd & i MAX_NUM) if (strcmp(clienti.name, p) = 0)return 0;i+;return 1;/SHOWvoid

4、showuser(c_client *p_client) int i = 0;char buf1024 = 0 ;strcpy(buf, 200rn);for (i = 0; i sockfd, buf, strlen(buf), 0);/ALLvoid sendto_all(c_client *p_client, char *buf) int i = 0;char sendbuf1024 = 0 ;sprintf(sendbuf, AFROMrn%srn%s, p_client-name, buf + 5);for (i = 0; i MAX_NUM; i+) if (clienti.soc

5、kfd != -1 & clienti.flg != -1)if(send(clienti.sockfd, sendbuf, strlen(sendbuf), 0) = 0)printf(send errrrrrn);exit(1);int findname(char *name) int i = 0;for (i = 0; i sockfd, sendbuf, strlen(sendbuf), 0); else sprintf(sendbuf, FROMrn%srn%s, p_client-name, buf + 4 + strlen(name) + 2);if(send(sock, sen

6、dbuf, strlen(sendbuf), 0)name);close(p_client-sockfd);p_client-sockfd = -1;p_client-pid = -1;p_client-flg = -1;sprintf(buf,NOTICE1rn%s退出聊天室rnrn,p_client-name);memset(p_client-name,0,20);for(i=0;inext != NULL)memset(buf,0,1024);pthread_rwlock_rdlock(&idx_lock);idx = find_fd(client);pthread_rwlock_unl

7、ock(&idx_lock);clientidx.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,NOTICErn您已被唤醒,请继续操作rnrn);send(clientidx.sockfd,buf,strlen(buf),0);if (pthread_create(&clientidx.pid, NULL, (void *

8、)pthread_fun,(void *) &clientidx) != 0) perror(pthread_create);exit(1);pthread_detach(clientidx.pid);void pthread_fun(void* cclient) c_client *p_client = (c_client *) cclient;char bufMAX_SIZE = 0 ;char sendbuf1024 = 0 ;int i, n;char *p;sprintf(sendbuf, %s, NOTICErn通讯通道开启rnrn);if (send(p_client-sockf

9、d, sendbuf, strlen(sendbuf), 0) sockfd, buf, sizeof(buf) - 1, MSG_NOSIGNAL);if (n sockfd);p_client-sockfd = -1;break;if (logform(buf) if (cmpname(buf, p_client) = 0) send(p_client-sockfd, ERRORrn用户名重复rnrn, 26, 0);continue; else p_client-flg = 1;p = strtok(buf + 7, rnrn);strcpy(p_client-name, p);spri

10、ntf(sendbuf, 100rn%srnrn, p_client-name);send(p_client-sockfd, sendbuf, sizeof(sendbuf), 0);printf(%s进入聊天室n, p_client-name);for (i = 0; i sockfd & clienti.flg != -1)send(clienti.sockfd, sendbuf, sizeof(sendbuf), 0);memset(sendbuf, 0, 1024);while (1) memset(buf, 0, MAX_SIZE);if (n = recv(p_client-soc

11、kfd, buf, MAX_SIZE, 0) sockfd, ERRORrn信息不符合协议要求rnrn,38, 0); else send(p_client-sockfd, ERRORrn未登录,请您登录再进行其他操作rnrn, 56, 0);pthread_exit(NULL);int main() int ser_sockfd, clt_sockfd;struct sockaddr_in addr;int idx;char buf1024 = 0 ;/pthread_rwlock_t idx_lock,wait_lock;pthread_rwlock_init(&idx_lock, NUL

12、L);pthread_rwlock_init(&wait_lock, NULL);init_client();/创建服务器sockfdif (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);/设置端口可重用int opt = 1;sets

13、ockopt(ser_sockfd, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt);/将套接字绑定到服务器的网络地址上if (bind(ser_sockfd, (struct sockaddr*)&addr, sizeof(addr) = -1) perror(bind);exit(1);printf(bind successn);/监听连接请求-监听队列长度为10if (listen(ser_sockfd, 10) = -1) perror(listen);exit(1);printf(listen successn);while (1) if (c

14、lt_sockfd = accept(ser_sockfd, NULL, NULL) = -1) perror(accept);exit(1);pthread_rwlock_rdlock(&idx_lock);idx = find_fd(client);/printf(idx=%dn,idx);pthread_rwlock_unlock(&idx_lock);if (idx != -1) /连接末满clientidx.sockfd = clt_sockfd;if (pthread_create(&clientidx.pid, NULL,(void *) pthread_fun,(void *)

15、&clientidx) != 0) perror(pthread_create);exit(1);pthread_detach(clientidx.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

16、 = 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, NOTICErn服务器已满,请等候rnrn);/客户端接受 则等待if (send(temp_c1-sockfd, buf, strlen(buf), 0) = 0) printf(sendr errn);/* * client.c * * Creat

17、ed on: 2012-6-18 * Author: root */#include #include #include #include #include #include #include #include #include #include #include #define MAX_SIZE 1024#define PORT 7999static int FLAGE = -1;char name20 = 0;void fun_show(int sockfd)char sendbuf256 = 0;sprintf(sendbuf,SHOWrnrn);if(send(sockfd,sendb

18、uf,strlen(sendbuf),0)=0)printf(send errn);close(sockfd);exit(1);void fun_all(int sockfd)char sendbufMAX_SIZE = 0;sprintf(sendbuf,ALLrn,5);printf(输入发送的内容:n);scanf(%s,sendbuf+5);sprintf(sendbuf+strlen(sendbuf),rnrn);if(send(sockfd,sendbuf,strlen(sendbuf),0) = 0)printf(send errn);close(sockfd);exit(1);

19、void fun_one(int sockfd)char sendbufMAX_SIZE = 0;char name320 = 0;printf(输入聊天对象:);scanf(%s,name3);sprintf(sendbuf,TOrn%srn,name3);printf(输入聊天内容:n);scanf(%s,sendbuf+strlen(sendbuf);sprintf(sendbuf+strlen(sendbuf),rnrn);if(send(sockfd,sendbuf,strlen(sendbuf),0) = 0)printf(send errn);close(sockfd);exit

20、(1);void fun_quit(int sockfd)char sendbuf256 = QUITrnrn;if(send(sockfd,sendbuf,strlen(sendbuf),0) = 0)printf(send errn);close(sockfd);exit(1);void *pthread_fun(int *sock)int sockfd = *sock;char recvbuf1024 = 0;int n = 0;char *p,*q;char name220 = 0;while(1)memset(recvbuf,0,1024);n = recv(sockfd,recvb

21、uf,sizeof(recvbuf),0);if(n=0)printf(recv failedn);exit(1);if(!strncmp(recvbuf,NOTICErn通讯通道开启rnrn,30)printf(通讯通道开启n);FLAGE=1;if (!strncmp(recvbuf, 100rn, 5) char *p = strtok(recvbuf + 5, rnrn);/100rn:3个字符后取出rnrn前的名字strcpy(name2, p);printf(NOTICE%s进入聊天室n, name2);FLAGE = 4;if (!strncmp(recvbuf, ERRORrn

22、用户名重复rnrn, 26) printf(用户名重复n);FLAGE = 3;if (!strncmp(recvbuf, 200rn, 5) p = strtok(recvbuf+5,rnrn);while(p != NULL)printf(%sn,p);p = strtok(NULL,rnrn);printf(please input con:n);if(!strncmp(recvbuf,AFROMrn,7)/printf(recvbuf=%sn,recvbuf);p = strtok(recvbuf+6,rn);q = strtok(NULL,rnrn);printf(%s)群聊:%sn

23、,p, q);printf(please input con:n);if(!strncmp(recvbuf,FROMrn,6)p = strtok(recvbuf+6,rn);q = strtok(NULL,rnrn);printf(%s)私聊(%s):%sn,p,name,q);printf(please input con:n);if(!strncmp(recvbuf,ERROR2rn,8)p = strtok(recvbuf + 8, rn);printf(%sn, p);if(!strncmp(recvbuf,NOTICE1rn,9)p = strtok(recvbuf + 9, rn

24、);printf(用户%sn, p);if(!strncmp(recvbuf,NOTICErn服务器已满,请等候rnrn,37)printf(服务器已满,请等候n);FLAGE = 0;if(!strncmp(recvbuf,NOTICErn您已被唤醒,请继续操作rnrn,45)printf(你已经被唤醒,请继续操作n);FLAGE = 2;int main(int argc,char *argv)if(argc != 2)printf(input server ip:n);exit(1);pthread_t pid;int sockfd;struct sockaddr_in addr;cha

25、r recvbuf1024 = 0;char sendbuf1024 = 0;int k=0;int n;char str6 = 0;char *p,*q;if(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);if(inet_pton(AF_INET,argv1,(void *)&addr.sin_addr) 0)usleep(100);/让子进程先运行

26、while(FLAGE=0)printf(服务器已满,wait.n);sleep(1);tcflush(0,TCIFLUSH);while(FLAGE=2) /当FLAGE2时正好父进程运行,则等待,FLAGE=1usleep(100);if(FLAGE = 1)while(k3)/fflush(stdin);memset(name,0,20);printf(login:);scanf(%s,name);/fflush(stdin);sprintf(sendbuf,LOGINrn%srnrn,name);send(sockfd,sendbuf,strlen(sendbuf),0);memset

27、(sendbuf,0,1024);for(;)if(FLAGE=3 | FLAGE=4)break;if(FLAGE=3)k+;if(k=3)printf(输入过多,退出n);elseprintf(还有%d次机会登录n, 3 - k);FLAGE=1;continue;if(FLAGE=4)while(1)memset(str,0,6);scanf(%s,str);if(!strcmp(str,show)printf(显示在线用户:n);fun_show(sockfd);continue;else if(!strcmp(str,all)printf(群聊模式 );fun_all(sockfd)

28、;continue;else if(!strcmp(str,to)printf(私聊模式);fun_one(sockfd);continue;else if(!strcmp(str,quit)printf(退出聊天室n);fun_quit(sockfd);close(sockfd);return;else if(!strcmp(str,help)printf(all聊天内容 群聊n);printf(toname聊天内容 私聊n);printf(quit 退出程序n);printf(help 显示帮助信息n);printf(please input con:n);continue;elseprintf(请输入help查看指令:n);continue;/wait(NULL);专心-专注-专业

展开阅读全文
相关资源
相关搜索

当前位置:首页 > 教育专区 > 教案示例

本站为文档C TO C交易模式,本站只提供存储空间、用户上传的文档直接被用户下载,本站只是中间服务平台,本站所有文档下载所得的收益归上传人(含作者)所有。本站仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。若文档所含内容侵犯了您的版权或隐私,请立即通知得利文库网,我们立即给予删除!客服QQ:136780468 微信:18945177775 电话:18904686070

工信部备案号:黑ICP备15003705号-8 |  经营许可证:黑B2-20190332号 |   黑公网安备:91230400333293403D

© 2020-2023 www.deliwenku.com 得利文库. All Rights Reserved 黑龙江转换宝科技有限公司 

黑龙江省互联网违法和不良信息举报
举报电话:0468-3380021 邮箱:hgswwxb@163.com