`
wildcat11
  • 浏览: 4241 次
  • 性别: Icon_minigender_1
  • 来自: 上海
文章分类
社区版块
存档分类
最新评论

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

//保存socket
int 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,并将描述符值置为-1
	close(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;
}

0
2
分享到:
评论

相关推荐

    基于linux网络聊天室的设计实用文档doc.doc

    基于 Linux 网络聊天室的设计实用文档 基于 Linux 网络聊天室的设计实用文档是《Linux 操作系统》课程设计报告的一部分,该文档的目的是为了设计一个基于 Linux 平台的网络聊天室。该设计主要分为两部分,客户端...

    基于Linux网络聊天室的设计.doc

    在Linux环境下实现网络聊天室,主要涉及以下技术: 1.2.1 网络套接字(Socket) 网络套接字是进程间通信的一种方式,尤其适合网络通信。在聊天室中,服务器端通过监听套接字等待客户端的连接请求,客户端则通过...

    linux下的网络聊天室,代码克运行[归纳].pdf

    在Linux下的网络聊天室中,Socket接口被用于建立客户端与服务器之间的连接,实现数据传输。 3. **TCP/IP协议**:TCP(传输控制协议)和IP(网际协议)是互联网上最常用的通信协议。TCP负责可靠的数据传输,IP则负责...

    网络聊天室

    本项目通过详细分析了在Linux环境下实现网络聊天室的关键技术和设计思路。从需求分析、总体设计到详细设计,每个环节都进行了深入探讨。使用C语言和Socket编程技术,结合多线程机制,成功构建了一个稳定、高效的网络...

    基与PHP的网络聊天室系统文献综述

    2. 基于JAVA的聊天室:利用Java Applet与服务器端的聊天服务器程序交互,实现实时性。然而,Java虽然跨平台,但在处理中文文本时可能存在编码问题,导致乱码。 【基于PHP的网络聊天室系统】 PHP编写聊天室系统时,...

    用PHP实现Web页面无闪动刷新.pdf

    【标题】: "用PHP实现Web...同时,这种技术对于实时性要求高的应用,如聊天室、在线游戏或实时数据显示,具有显著优势。由于减少了不必要的页面跳转,不仅可以提高页面加载速度,还能减少服务器负载,提高系统效率。

    JAVA上百实例源码以及开源项目源代码

    将其解码,李四用张三的公钥加密信息,并发送给李四,张三用自己的私钥解密从李四处收到的信息…… Java利用DES私钥对称加密代码实例 同上 java聊天室 2个目标文件,简单。 java模拟掷骰子2个 1个目标文件,输出演示...

    嵌入式软件开发.doc

    1. **基于TCP的网络聊天室项目**: - **技术栈**:主要采用C语言、Socket编程、多线程技术和Signal信号机制。 - **应用场景**:适用于局域网内的即时通信。 - **关键点**:Socket编程实现数据传输、多线程技术...

    eiskaltdcpp:使用DC和ADC协议的文件共享程序

    公开聊天室: : Wiki: : 执照 该程序根据GNU通用公共许可证授权。 有关更多信息,请参见文件。 描述 EiskaltDC ++是一个跨平台程序,使用(DC,又称NMDC)和(ADC)协议。 它与DC ++,AirDC ++,FlylinkDC ++和...

    gcc3.4完全手册

    为了帮助用户更好地使用GCC,手册中还提供了获取帮助的各种途径,包括在线文档、邮件列表、IRC聊天室等。 #### 十三、为GCC开发做贡献 最后,手册鼓励有能力的开发者参与到GCC的开发中来,贡献自己的力量,共同推动...

    Ubuntu桌面入门指南

    - **GNU**:Ubuntu采用了大量的GNU工具和软件,因此也被视为GNU/Linux的一部分。 - **获得Ubuntu**: - 通过官方网站下载ISO镜像文件进行安装。 - 可以选择使用Live CD/DVD或USB启动盘来体验Ubuntu而无需安装。 ...

Global site tag (gtag.js) - Google Analytics