Unix系统下的基于TCP通信的聊天室

这是本人在学习Unix C是的练习
//server.cpp
//TCP聊天室服务器
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
struct client{
	char name[20];//客户端连接上来时 输入的姓名
	int fds;//客户端的socket
};
struct client c[100]={0};//最多记录100个sockfd,最多允许100个用户进入
int sockfd;//服务器的sockfd
int size = 0;//记录客户端的个数,数组的索引
int online = 0;
char filename[4096] = {0};
char* IP = "192.168.66.42";//获取本机IP
short PORT = 20000;
typedef struct sockaddr SA;//用作通信地址类型转换的时候使用

//初始化服务器的网络,创建socket..
void init(){
	system("clear");
	printf("聊天室服务器开始启动..\n");
	//创建socket
	sockfd = socket(PF_INET,SOCK_STREAM,0);
	if(sockfd == -1){
		perror("创建socket失败");
		printf("服务器启动失败\n");
		exit(-1);
	}
	//准备通信地址
	struct sockaddr_in addr;//网络通信的地址信息
	addr.sin_family = PF_INET;//协议簇
	addr.sin_port = htons(PORT);//端口
	addr.sin_addr.s_addr = inet_addr(IP);//IP地址结构体
	int reuseaddr = 1;
	setsockopt(sockfd,SOL_SOCKET,SO_REUSEADDR,&reuseaddr,sizeof(reuseaddr));
	//绑定socket和通信地址
	if(bind(sockfd,(SA*)&addr,sizeof(addr))==-1){
		perror("绑定失败");
		printf("服务器启动失败\n");
		exit(-1);
	}
	printf("成功绑定\n");
	//设置监听
	if(listen(sockfd,100)==-1){
		perror("设置监听失败");
		printf("服务器启动失败\n");
		exit(-1);
	}
	printf("初始化服务器成功\n");
	//等待客户端连接和通信部分写到另一个函数中
}
//用来分发消息的函数
void sendMsgToAll(char * msg){
	int i=0;
	for(;i0){//接受到名字
			strcpy(c[size].name,name);
		}
		m_id = size;
		size++;
	//进入线程之后,先群发一条提示,提示某某客户端连接上来
	char tishi[100]={};
	sprintf(tishi,"%s 上线\n",c[size-1].name);
	online += 1;
	sendMsgToAll(tishi);
	int fd = *(int*)p;
	printf("Name:%s 上线\n",c[size-1].name);
	//通信,接受消息,分发消息
	while(1){
		char buf[100]={};
		recv(fd,buf,sizeof(buf),0);
		if(strncmp(buf,"bye",3) == 0/*recv(fd,buf,sizeof(buf),0)<=0*/){//接受信息
//			printf("fd=%dquit\n",fd);//recv函数返回小于0,则
			//表示有客户端断开,打印quit
			//之后将退出的客户端的socket描述符重新置成0
			int i;
			for(i=0;i

//client.cpp
//聊天室客户端
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 

void sig_close();
int sockfd;//客户端socket
char *IP="192.168.66.42";//本地IP
short PORT=20000;//服务器服务端口
typedef struct sockaddr SA;
char name[30];//用于存放聊天人的昵称

//客户端也分为几步:
//启动客户端,连接服务器
void init(){
	printf("聊天室客户端开始启动\n");
	sockfd=socket(PF_INET,SOCK_STREAM,0);
	struct sockaddr_in addr;
	addr.sin_family = PF_INET;
	addr.sin_port = htons(PORT);
	addr.sin_addr.s_addr = inet_addr(IP);
	if(connect(sockfd,(SA*)&addr,sizeof(addr))==-1){
		perror("无法连接到服务器");
		printf("客户端启动失败\n");
		exit(-1);
	}
	printf("客户端启动成功\n");
}
//开始通信
void start(){
	//发送消息之前
	//启动一个线程,用来接受服务器发过来的消息
	pthread_t pid;
	void* recv_thread(void*);//线程函数的声明
	pthread_create(&pid,0,recv_thread,0);
	char buf[100] = {0};
	while(1){//内部不断的发送数据
		bzero(buf,100);
		fgets(buf,sizeof(buf),stdin);
		if(strncmp(buf,"clear",5) == 0){
			system("clear");
		}
		else if(strncmp(buf,"bye",3) == 0){
			sig_close();
		}
		else{
			send(sockfd,buf,sizeof(buf),0);//发送消息给服务器
		}
	}
}
void * recv_thread(void* p){
	while(1){
		char buf[100]={};//存储读到的消息
		if(recv(sockfd,buf,sizeof(buf),0)<=0){//接收出错
			return ;//结束线程
		}
		if(strncmp(buf,"close",5) == 0){
			printf("服务器已关闭,现在退出客户端\n");
			close(sockfd);
			exit(0);
		}
		else{
			printf("%s",buf);
		}
	}
}
void sig_close(){
	//关闭客户端的socket
	char buf[] = "bye";
	send(sockfd,buf,sizeof(buf),0);
	close(sockfd);
	exit(0);
}
int main(){
	//f发信号,关闭socket
	signal(SIGINT,sig_close);//自定义信号处理函数,做好善后工作	
	printf("请输入您的名字:");
	scanf("%s",name);
	scanf("%*[^\n]");
	scanf("%*c");
	init();//启动客户端,连接服务器
	send(sockfd,name,sizeof(name),0);//把名字给服务器
	start();//通信
}

时间比较紧,所以功能不太完善
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值