首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 操作系统 > UNIXLINUX >

Linux上GNU C实现的简单聊天室程序

2012-12-26 
Linux下GNU C实现的简单聊天室程序闲暇之余,利用linux下的多线程和网络知识,写了个简单多人聊天程序,意在

Linux下GNU C实现的简单聊天室程序
闲暇之余,利用linux下的多线程和网络知识,写了个简单多人聊天程序,意在说明用GNU C写网络类程序的步骤和需要注意的问题以及linux多线程的使用方法。

编译:
gcc -Wall -o server -lpthread server.c
gcc -Wall -o client -lpthread client.c

服务器端:

#include <sys/types.h>#include <sys/socket.h>#include <sys/wait.h>#include <stdio.h>#include <stdlib.h>#include <errno.h>#include <string.h>#include <sys/un.h>#include <sys/time.h>#include <sys/ioctl.h>#include <unistd.h>#include <netinet/in.h>#include <pthread.h>//定义同时聊天的人数#define COUNT 5//保存socketint socket_fd[COUNT];//线程的入口函数void pthread_function(int client_fd){char message[1500];char buf[1024];int i,recvbytes;char name[20];//首次连接时,接受并保存客户端名字recvbytes = recv(client_fd, name, 20, 0);name[recvbytes]=':';name[recvbytes+1]='\0';while(1){if((recvbytes = recv(client_fd, buf, 1024, 0))==-1){perror("recv error");exit(1);}if(recvbytes==0){printf("%sbye!\n",name);break;}buf[recvbytes]='\0';for(i=0;i<COUNT;i++){if(socket_fd[i]==-1){continue;}else{message[0]='\0';strcat(message,name);strcat(message,buf);if(send(socket_fd[i],message,strlen(message),0)==-1){perror("send error");exit(1);}}}}//断开时关闭socket,并将描述符值置为-1close(client_fd);for(i=0;i<COUNT;i++){if(socket_fd[i]==client_fd){socket_fd[i]=-1;}}//退出线程pthread_exit(NULL);}int main(){//初始化socket数组int i;for(i=0;i<COUNT;i++){socket_fd[i]=-1;}pthread_t id;int sockfd,client_fd;socklen_t sin_size;struct sockaddr_in my_addr;struct sockaddr_in remote_addr;if((sockfd = socket(AF_INET,SOCK_STREAM,0))==-1){perror("socket");exit(1);}//配置信息my_addr.sin_family=AF_INET;my_addr.sin_port=htons(12345); my_addr.sin_addr.s_addr=INADDR_ANY;bzero(&(my_addr.sin_zero),8);//绑定if(bind(sockfd,(struct sockaddr *)&my_addr,sizeof(struct sockaddr))==-1){perror("bind");exit(1);}//监听if(listen(sockfd,10)==-1){perror("listen");exit(1);}i=0;while(1){sin_size=sizeof(struct sockaddr_in);if((client_fd=accept(sockfd,(struct sockaddr *)&remote_addr,&sin_size))==-1){perror("accept");exit(1);}//找到一个可用的socket位置while(socket_fd[i]!=-1)i=(i+1)%COUNT;//保存socket并启动线程处理socket_fd[i]=client_fd;pthread_create(&id,NULL,(void *)pthread_function,(int *)client_fd);}}

客户端:
#include <sys/types.h>#include <sys/socket.h>#include <sys/wait.h>#include <stdio.h>#include <stdlib.h>#include <errno.h>#include <string.h>#include <sys/un.h>#include <sys/time.h>#include <sys/ioctl.h>#include <unistd.h>#include <netinet/in.h>#include <arpa/inet.h>#include <pthread.h>char recv_buf[1500],send_buf[1024];//线程入口函数,负责显示接收到的信息void pthread_function(int sockfd){int recvbytes;while(1){if((recvbytes = recv(sockfd, recv_buf, 1500, 0))==-1){perror("recv error");exit(1);}else{recv_buf[recvbytes]='\0';printf("%s\n", recv_buf);}}}int main(void){pthread_t id;int sockfd;struct sockaddr_in server_addr;//参数设置server_addr.sin_family = AF_INET;server_addr.sin_port = htons(12345);server_addr.sin_addr.s_addr = inet_addr("127.0.0.1");if((sockfd = socket(AF_INET, SOCK_STREAM, 0))==-1){perror("socket error");exit(1);}//连接if(connect(sockfd, (struct sockaddr*)&server_addr,sizeof(server_addr))==-1){perror("connect error");exit(1);}//输入客户端名字char name[20];printf("input your name:");scanf("%s",name);send(sockfd,name,strlen(name),0);pthread_create(&id,NULL,(void *)pthread_function,(int *)sockfd);while(1){gets(send_buf);if(send(sockfd,send_buf,strlen(send_buf),0)==-1){perror("send error");exit(1);}sleep(1);}//关闭socket并取消线程close(sockfd);pthread_cancel(id);return 0;}

热点排行