聊天室项目

网络编程项目要求
一、 实现目标
一个在 Linux 下可以使用的聊天软件,要求至少实现如下功能:
1. 采用 Client/Server 架构
2. Client A 登陆聊天服务器前,需要注册自己的 ID 和密码
3. 注册成功后,Client A 就可以通过自己的 ID 和密码登陆聊天服务器
4. 多个 Client X 可以同时登陆聊天服务器之后,与其他用户进行通讯聊天
5. Client A 成功登陆后可以查看当前聊天室内其他在线用户 Client x
6. Client A 可以选择发消息给某个特定的 Client X,即”悄悄话”功能
7. Client A 可以选择发消息全部的在线用户,即”群发消息”功能
8. Client A 在退出时需要保存聊天记录
9. Server 端维护一个所有登陆用户的聊天会的记录文件,以便备查
可以选择实现的附加功能:
1. Server 可以内建一个特殊权限的账号 admin,用于管理聊天室
2. Admin 可以将某个 Client X “提出聊天室”
3. Admin 可以将某个 Client X ”设为只能旁听,不能发言”
4. Client 端发言增加表情符号,可以设置某些自定义的特殊组合来表达感
情.如输入:),则会自动发送”XXX 向大家做了个笑脸”
5. Client 段增加某些常用话语,可以对其中某些部分进行”姓名替换”,例
如,输入/ClientA/welcome,则会自动发送”ClientA 大侠,欢迎你来到咱
们的聊天室”
二、 考核内容
网络编程:
设计 Client 和 Server 的通讯协议,并实现 Server 向登陆客户的消息发送
文件 I/O 编程:
设计聊天记录的文件格式
设计注册用户和密码及配置参数的”数据库”文件
多线程或进程编程:
Server 端需要至少创建 2 个线程或进程,一个用于监听 Client 端的连接请求,
一个用于给登陆的 Client 用户列表发送某个 client 的消息内容.

服务器端:

Server_main.c

#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include "Linklist.h"
#include"server.h"

#define PORT 8888


int main()
{
	int sockfd, ret, length, fd[100] = {0} , i = 0, j, to_fd, vip = 0;
	struct sockaddr_in server_addr;
	struct sockaddr_in client_addr;
	struct infor SendBuf;

	Linklist list;//鍒涘缓鍦ㄧ嚎閾捐〃
	
 	ret = ListInit(&list);
	if(ret == SUCCESS)
	{
		printf("Init Success!\n");
	}

	fd_set ReadFd, TmpFd;
	int MaxFd;

	sockfd = socket(PF_INET, SOCK_STREAM, 0);
	if (-1 == sockfd)
	{
		perror("socket");
		exit(1);
	}
	memset(&server_addr, 0, sizeof(struct sockaddr_in));
	server_addr.sin_family = PF_INET;
	server_addr.sin_port = PORT;
	server_addr.sin_addr.s_addr = inet_addr("127.0.0.1");

	int opt = 1;
	setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt));//璁剧疆濂楁帴瀛楅€夐」

	ret = bind(sockfd, (struct sockaddr *)&server_addr, sizeof(struct sockaddr_in));
	if (-1 == ret)
	{
		perror("bind");
		exit(1);
	}

	printf("WAITING FOR CONNECT...\n");

	ret = listen(sockfd, 5);
	if (-1 == ret)
	{
		perror("listen");
		exit(1);
	}

	FD_ZERO(&ReadFd);
	FD_ZERO(&TmpFd);
	FD_SET(sockfd, &ReadFd);
	MaxFd = sockfd;
	
	while(1)
	{
	 
 
TmpFd = ReadFd; ret = select(MaxFd + 1, &TmpFd, NULL, NULL, NULL); //鐩戞帶 if(-1 == ret) { perror("select"); exit(1); } if(FD_ISSET(sockfd, &TmpFd))// 妫€娴嬫槸鍚﹀彂鐢熷彉鍖? { length = sizeof(client_addr); fd[i] = accept(sockfd, (struct sockaddr*)&client_addr, &length); if (-1 == fd[i]) { perror("accept"); exit(1); } printf("Accept %d, Port = %d\n", fd[i], client_addr.sin_port); FD_SET(fd[i], &ReadFd); MaxFd = fd[i]; i++; } else { for(j = 0; j < i; j++) { if(FD_ISSET(fd[j], &TmpFd)) { memset(&SendBuf, 0, sizeof(SendBuf)); ret = recv(fd[j], (void *)&SendBuf, sizeof(SendBuf), 0); if(-1 == ret) { perror("recv"); exit(1); } if(ret > 0) { printf("鎺ユ敹鏉ヨ嚜瀹㈡埛鏈?d鐨勪俊鍙凤細%d \n", fd[j], SendBuf.flag); } else { Linklist q = list->next; while(q) { if(fd[j] == q->fd) { ret = ListDelate(list, q->name); if(ret == SUCCESS) { printf("涓嬬嚎鎴愬姛\n"); } break; } q = q->next; } printf("瀹㈡埛鏈?d閫€鍑篭n", fd[j]); close(fd[j]); FD_CLR(fd[j], &ReadFd); break; } if(SendBuf.flag == 1) /*妫€娴嬩俊鍙蜂负鐧诲綍*/ { ret = Log_check(&SendBuf, &vip); /*澶勭悊鐧诲綍淇″彿*/ if(SUCCESS == ret) { ret = ListLocate(list, SendBuf.name);//鏌ョ湅鏄惁宸插湪绾? if(FAILED == ret)//濡傛灉鐢ㄦ埛涓嶅湪绾? { ListInsert(list, SendBuf.name, fd[j], 1);//鍔犲叆鍦ㄧ嚎閾捐〃 printf("vip = %d\n", vip); strcpy(SendBuf.massage, "logsuccess"); printf("%s 鐧诲綍鎴愬姛\n", SendBuf.name); ret = send(fd[j], (void *)&SendBuf, sizeof(SendBuf), 0); } else { strcpy(SendBuf.massage, "isonline"); ret = send(fd[j], (void *)&SendBuf, sizeof(SendBuf), 0); } } else { strcpy(SendBuf.massage, "error"); ret = send(fd[j], (void *)&SendBuf, sizeof(SendBuf), 0); } } if(SendBuf.flag == 2) /*妫€娴嬩俊鍙蜂负娉ㄥ唽*/ { printf("澶勭悊娉ㄥ唽淇℃伅\n"); ret = Reg_check(&SendBuf); /*澶勭悊娉ㄥ唽淇″彿*/ if(SUCCESS == ret) { strcpy(SendBuf.massage, "regsuccess"); printf("%s娉ㄥ唽鎴愬姛\n", SendBuf.name); ret = send(fd[j], (void *)&SendBuf, sizeof(SendBuf), 0); if(-1 == ret) { perror("send1"); exit(1); } } else { strcpy(SendBuf.massage, "regfailed"); ret = send(fd[j], (void *)&SendBuf, sizeof(SendBuf), 0); if(-1 == ret) { perror("send1"); exit(1); } } } if(SendBuf.flag == 3)/*妫€娴嬩俊鍙蜂负绠$悊鍛樼櫥褰?/ { if(!strcmp(SendBuf.passwd, "admin")) { ListInsert(list, SendBuf.name, fd[j], 1);//鍔犲叆鍦ㄧ嚎閾捐〃 strcpy(SendBuf.massage, "logsuccess"); printf("%s %s\n", SendBuf.name, SendBuf.massage); ret = send(fd[j], (void *)&SendBuf, sizeof(SendBuf), 0); if(-1 == ret) { perror("send1"); exit(1); } } else { strcpy(SendBuf.massage, "regfailed"); ret = send(fd[j], (void *)&SendBuf, sizeof(SendBuf), 0); } } if(SendBuf.flag == 4)/*妫€娴嬩俊鍙蜂负鏌ョ湅鍦ㄧ嚎鐢ㄦ埛*/ { Linklist p = list->next; while(p) { memset(&SendBuf, 0, sizeof(SendBuf)); SendBuf.flag = 4; strcpy(SendBuf.massage, p->name); ret = send(fd[j], (void*)&SendBuf, sizeof(SendBuf), 0); printf("鏌ョ湅鍦ㄧ嚎鐨勪汉\n"); p = p->next; } } if(SendBuf.flag == 5)/*妫€娴嬩俊鍙蜂负鍙戣捣鑱婂ぉ璇锋眰*/ { ret = Check_talk(&SendBuf, list);//鍒ゆ柇鏄惁绂佽█ if(SUCCESS == ret) { Check_online(&SendBuf, list);//鍒ゆ柇鏄惁鍦ㄧ嚎 } ret = send(fd[j], (void*)&SendBuf, sizeof(SendBuf), 0); } if(SendBuf.flag == 6) /*妫€娴嬩俊鍙蜂负寮€濮嬬鑱?/ { Chat_log(&SendBuf);//璁板叆鏈嶅姟鍣ㄨ亰澶╂棩蹇? to_fd = SendBuf.fd;//鎺ユ敹瀵规柟鐨刦d printf("瀵规柟瀹㈡埛鏈猴細%d\n", to_fd); ret = send(to_fd, (void*)&SendBuf, sizeof(SendBuf), 0); } if(SendBuf.flag == 7) /*妫€娴嬩俊鍙蜂负鍙戦€佹倓鎮勮瘽*/ { Chat_log(&SendBuf); to_fd = SendBuf.fd;//鎺ユ敹瀵规柟鐨刦d printf("瀵规柟瀹㈡埛鏈猴細%d\n", to_fd); ret = send(to_fd, (void*)&SendBuf, sizeof(SendBuf), 0); } if(SendBuf.flag == 8) /*妫€娴嬩俊鍙蜂负缇ゅ彂娑堟伅*/ { ret = Check_talk(&SendBuf, list);//鍒ゆ柇鏄惁琚瑷€ if(SUCCESS == ret) { Chat_log(&SendBuf); Travel(list, SendBuf);//閬嶅巻缇ゅ彂鍦ㄧ嚎閾捐〃 } else { memset(SendBuf.massage, 0, sizeof(SendBuf.massage)); strcpy(SendBuf.massage, "untalk"); ret = send(fd[j], (void*)&SendBuf, sizeof(SendBuf), 0); } } if(SendBuf.flag == 9) /*妫€娴嬩俊鍙蜂负绂佽█*/ { ret = UnTalk(&SendBuf, list); send(fd[j], (void*)&SendBuf, sizeof(SendBuf), 0); if(ret != SUCCESS && ret != FAILED) { memset(SendBuf.massage, 0, sizeof(SendBuf.massage)); strcpy(SendBuf.massage, "untalk"); send(ret, (void*)&SendBuf, sizeof(SendBuf), 0); } } if(SendBuf.flag == 10) /*妫€娴嬩俊鍙蜂负瑙i櫎绂佽█*/ { ret = ReTalk(&SendBuf, list); send(fd[j], (void*)&SendBuf, sizeof(SendBuf), 0); if(ret != SUCCESS && ret != FAILED) { memset(SendBuf.massage, 0, sizeof(SendBuf.massage)); strcpy(SendBuf.massage, "talk"); send(ret, (void*)&SendBuf, sizeof(SendBuf), 0); } } if(SendBuf.flag == 11) /*妫€娴嬩俊鍙蜂负韪汉鎴栦笅绾?/ { ret = ListDelate(list, SendBuf.to_name); if(SUCCESS == ret) { printf("%s涓嬬嚎鎴愬姛锛乗n", SendBuf.to_name); strcpy(SendBuf.massage, "success"); send(fd[j], (void*)&SendBuf, sizeof(SendBuf), 0); } else { printf("涓嬬嚎澶辫触锛乗n"); strcpy(SendBuf.massage, "failed"); send(ret, (void*)&SendBuf, sizeof(SendBuf), 0); } } if(SendBuf.flag == 12)/*妫€娴嬩俊鍙蜂负鏌ョ湅鎵€鏈夎亰澶╄褰?/ { Send_Chatlog(fd[j]); } if(SendBuf.flag == 13) // 瀹㈡埛鏈洪€€鍑? { printf("瀹㈡埛鏈?d閫€鍑篭n", fd[j]); close(fd[j]); FD_CLR(fd[j], &ReadFd); break; } } } } } return 0; }
server.c

#include"server.h"

int Recheck(struct infor *user)//娉ㄥ唽妫€鏌?
{
	int ret, row, column;
	char **result; 
	char *errmsg;
	sqlite3 *pdb;
	char sql[100] = {0};
	
	if(strcmp(user->name, "admin") == 0)/*妫€鏌ユ槸鍚︿笌admin閲嶅悕*/
	{
		return FAILED;
	}

	/*鎵撳紑鏁版嵁搴?/
	ret = sqlite3_open("data.db", &pdb);
	if(ret != SQLITE_OK)
	{
		perror("sqlite3_open");
		exit(1);
	}
	/*妫€鏌ユ槸鍚﹀垱寤哄垪琛?/
	sprintf(sql, "create table if not exists member (name text, passwd text, vip integer);");
	ret =  sqlite3_exec(pdb, sql, NULL, NULL, NULL);
	if(ret != SQLITE_OK)
	{
		perror("sqlite3_exec1");
		exit(1);
	}
	/*妫€鏌ュ笎鍙锋槸鍚﹀凡瀛樺湪*/
	memset(sql, 0, sizeof(sql));
	sprintf(sql," select * from member where name = '%s';", user->name);
	ret = sqlite3_get_table(pdb, sql, &result, &row, &column, &errmsg);
	if(ret != SQLITE_OK)
	{
		perror("sqlite3_exec2");
		exit(1);
	}
	if(row != 0)
	{
		sqlite3_close(pdb);
		return FAILED;	
	}

	/*娉ㄥ唽*/
	memset(sql, 0, sizeof(sql));
	sprintf(sql, "insert into member (name, passwd, vip) values ('%s', '%s', '0');", user->name, user->passwd);
	ret = sqlite3_exec(pdb, sql, NULL, NULL, NULL);
	if(ret != SQLITE_OK)
	{
		perror("sqlite3_exec3");
		exit(1);
	}
	/*鍏抽棴*/
	sqlite3_close(pdb);
	return SUCCESS;
}

int Log_check(struct infor *user, int *vip)//妫€鏌ョ櫥褰曚俊鎭槸鍚︽纭?
{
	int ret, row, column;
	char **result;
	char *errmsg;
	sqlite3 *pdb;
	char sql[100] = {0};
	
	if(strcmp(user->name, "admin") == 0)
	{
		return FAILED;
	}
	/*鎵撳紑鏁版嵁搴?/
	ret = sqlite3_open("data.db", &pdb);
	if(ret != SQLITE_OK)
	{
		perror("sqlite3_open");
		exit(1);
	}
	/*妫€鏌ユ槸鍚﹀垱寤哄垪琛?/
	sprintf(sql, "create table if not exists member (name text, passwd text, vip integer);");
	ret =  sqlite3_exec(pdb, sql, NULL, NULL, NULL);
	if(ret != SQLITE_OK)
	{
		perror("sqlite3_exec1");
		exit(1);
	}
	/*妫€鏌ュ笎鍙锋槸鍚﹀瓨鍦?/
	memset(sql, 0, sizeof(sql));
	sprintf(sql," select * from member where name = '%s' and passwd = '%s';", user->name, user->passwd);
	ret = sqlite3_get_table(pdb, sql, &result, &row, &column, &errmsg);
	if(ret != SQLITE_OK)
	{
		perror("sqlite3_exec2");
		exit(1);
	}
	if(row != 0)
	{	
		memset(sql, 0, sizeof(sql));
		sprintf(sql," select * from member where name = '%s' and vip = '1';", user->name);
		sqlite3_get_table(pdb, sql, &result, &row, &column, &errmsg);
		if(row != 0)
		{	
			*vip = 1;
		}
		else
		{
			*vip = 0;	
		}
		sqlite3_close(pdb);
		return SUCCESS;	
	}
	/*CLOSE*/
	sqlite3_close(pdb);

	return FAILED;	
}

int Chat_log(struct infor *SendBuf)//璁板綍鎵€鏈夎亰澶╀俊鎭?
{
	int ret;
	FILE *fp;
	time_t t;
	char buf[200] ={0};
	fp = fopen("chat_log.txt", "a+");
	if(NULL == fp)
	{
		perror("fopen");
		exit(1);
	}
	time(&t);//鑾峰彇鏃堕棿鎴?
	sprintf(buf, "%s%s瀵?s璇? %s", ctime(&t), SendBuf->name, SendBuf->to_name, SendBuf->massage);
	ret = fwrite((void *)buf, 1, sizeof(buf), fp);
	fclose(fp);
	return SUCCESS;
}

int Send_Chatlog(int fd)//鍙戦€佹墍鏈夌敤鎴疯亰澶╄褰?
{
	int ret;
	struct infor SendBuf;
	FILE *fp;
	SendBuf.flag = 12;
	fp = fopen("chat_log.txt", "a+");
	if(NULL == fp)
	{
		perror("fopen");
		exit(1);
	}
	fseek(fp, 0, SEEK_SET);
	while(fread((void *)SendBuf.massage, 1, sizeof(SendBuf.massage), fp))
	{
		ret = send(fd, (void*)&SendBuf, sizeof(SendBuf), 0);
		memset(SendBuf.massage, 0, sizeof(SendBuf.massage));
	}
	fclose(fp);
	return SUCCESS;
}

int Check_talk(struct infor *SendBuf, Linklist list)//鍒ゆ柇鐢ㄦ埛鏄惁琚瑷€
{
	Linklist p = list->next;
	while(p)
	{
		if(!strcmp(SendBuf->name, p->name))	
		{
			if(0 == p->talk)
			{
				strcpy(SendBuf->massage, "untalk");
				printf("璇ョ敤鎴峰凡琚瑷€\n");
				return FAILED;
			}
		}
		p = p->next;
	}
	return SUCCESS;
}
int Check_online(struct infor *SendBuf, Linklist list)//鍒ゆ柇瀵规柟鐢ㄦ埛鏄惁鍦ㄧ嚎
{
	Linklist p = list->next;
	while(p)
	{
		if(!strcmp(SendBuf->to_name, p->name))	
		{
			SendBuf->fd = p->fd;
			printf("fd = %d\n",SendBuf->fd);
			strcpy(SendBuf->massage, "chatsuccess");
			printf("flag5 success\n");
			return SUCCESS;
		}
		p = p->next;	
	}
	if(NULL == p)
	{
		strcpy(SendBuf->massage, "chatfailed");
	}
	return FAILED;
}
int UnTalk(struct infor *SendBuf, Linklist list)//绂佽█
{
	int fd1;
	Linklist p = list->next;
	while(p)
	{
		if(!strcmp(SendBuf->to_name, p->name))	
		{
			if(0 == p->talk)
			{
				strcpy(SendBuf->massage, "success");
				return SUCCESS;
			}
			p->talk = 0;
			fd1 = p->fd;
			strcpy(SendBuf->massage, "success");
			printf("绂佽█%s鎴愬姛\n", SendBuf->to_name);
			return fd1;
		}
		else
			p = p->next;
	}
	if(NULL == p)
	{
		printf("绂佽█澶辫触\n");
		strcpy(SendBuf->massage, "failed");
	}	
	return FAILED;
}

int ReTalk(struct infor *SendBuf, Linklist list)
{
	Linklist p = list->next;
	int fd2;
	while(p)
	{
		if(!strcmp(SendBuf->to_name, p->name))	
		{
			if(1 == p->talk)
			{
				strcpy(SendBuf->massage, "success");
				return SUCCESS;
			}
			p->talk = 1;
			fd2 = p->fd;
			printf("瑙i櫎%s鐨勭瑷€鎴愬姛锛乗n", SendBuf->to_name);
			strcpy(SendBuf->massage, "success");
			return fd2;
		}
		else
			p = p->next;
	}
	if(NULL == p)
	{
		strcpy(SendBuf->massage, "failed");
	}
	return FAILED;
}

int Travel(Linklist L, struct infor SendBuf)
{
	int ret;
	Linklist p = L->next;
	while(p)
	{
		if(strcmp(p->name, SendBuf.name))
		{
			ret = send(p->fd, (void*)&SendBuf, sizeof(SendBuf), 0);	
		}
		p = p->next;
	}
	return SUCCESS;
}
客户端:
Client_main.c
#include <stdio.h>
#include "client.h"
#include<pthread.h>

#define PORT 8888

int fd = -1;
FILE *fp;

void *My_recv(void *arg)
{
	int ret;
	struct infor RecvBuf;
	char chat_log[100] = {0};//鑱婂ぉ璁板綍鏂囦欢
	char buf[200] = {0};
	time_t t;
	while (1)
	{
		ret = recv(*(int *)arg, &RecvBuf, sizeof(RecvBuf), 0);
		if (-1 == ret)
		{
			perror("recv");
			return 0;
		}
		switch(RecvBuf.flag)
		{
			case 1:
				if(!strcmp(RecvBuf.massage, "logsuccess"))
				{
					printf("宸茬櫥褰?\n");
					user_log = 1;
					sprintf(chat_log, "%s.txt", RecvBuf.name);
					fp = fopen(chat_log, "a+");//鐢熸垚鏂囦欢淇濆瓨鑱婂ぉ璁板綍
					if(NULL == fp)
					{
						perror("fopen2");
						exit(3);
					}
				}
				else
				{
					printf("鐧诲綍澶辫触!\n");
				}
				break;
			case 2:
				if(!strcmp(RecvBuf.massage, "regsuccess"))
				{		
					printf("娉ㄥ唽鎴愬姛锛?\n");
				}
				else
				{
					printf("娉ㄥ唽澶辫触!\n");
				}	
				break;
			case 3:
				if(!strcmp(RecvBuf.massage, "logsuccess"))
				{
					admin_log = 1;
					printf("绠$悊鍛樺凡鐧诲綍!\n");
				}
				else if(!strcmp(RecvBuf.massage, "isonline"))
				{
					printf("鐢ㄦ埛宸插湪鍏朵粬鍦版柟鐧诲綍!\n");
				}
				else
				{
					printf("鐢ㄦ埛鍚嶆垨瀵嗙爜閿欒锛乗n");
				}
				break;
			case 4:
				printf("鍦ㄧ嚎鐢ㄦ埛: %s\n", RecvBuf.massage);
				break;
			case 5://鎺ュ彈鍙戣捣鑱婂ぉ鐨勮姹?
				if(!strcmp(RecvBuf.massage, "chatsuccess"))
				{
					printf("寮€濮嬭亰澶?\n");
					fd = RecvBuf.fd;//杩斿洖瀵规柟鐨刦d
				//	printf("fdrecv = %d\n",fd);
				}
				else if(!strcmp(RecvBuf.massage, "untalk"))
				{
					printf("浣犲凡琚鐞嗗憳绂佽█\n");
				}
				else
				{
					printf("瀵规柟鏈湪绾?\n");
				}
				break;
			case 6://寮€濮嬬鑱?
				printf("\t\t\t%s:%s\n", RecvBuf.name, RecvBuf.massage);
				time(&t);//鑾峰彇鏃堕棿鎴?
				sprintf(buf, "%s%s瀵逛綘璇?%s", ctime(&t), RecvBuf.name, RecvBuf.massage);
				ret = fwrite((void *)buf, 1, sizeof(buf), fp);
				memset(buf, 0, strlen(buf));
				break;
			case 7://鎺ユ敹鎮勬倓璇?
				printf("\t\t\t鏈変汉瀵逛綘璇翠簡涓€鍙ユ倓鎮勮瘽锛?s\n",RecvBuf.massage);
				break;
			case 8://鎺ュ彈缇ゅ彂娑堟伅
				if(!strcmp(RecvBuf.massage, "untalk"))
				{
					printf("浣犲凡琚瑷€锛乗n");
				}
				else
				{
					printf("\t\t\t鏉ヨ嚜%s鐨勭兢鍙戞秷鎭?%s\n", RecvBuf.name, RecvBuf.massage);
				}
				break;
			case 9: //鎺ユ敹绂佽█鎿嶄綔鐨勮繑鍥炵粨鏋?
				if(!strcmp(RecvBuf.massage, "untalk"))
				{
					printf("浣犲凡琚鐞嗗憳绂佽█\n");
				}
				else if(!strcmp(RecvBuf.massage, "success"))
				{
					printf("%s宸茶绂佽█\n", RecvBuf.to_name);
				}
				else
				{
					printf("瀵规柟鏈湪绾縗n");
				}
				break;
			case 10:
				if(!strcmp(RecvBuf.massage, "talk"))
				{
					printf("浣犲凡琚鐞嗗憳瑙i櫎绂佽█\n");
				}
				else if(!strcmp(RecvBuf.massage, "success"))
				{
					printf("%s宸茶В闄ょ瑷€\n", RecvBuf.to_name);
				}
				else
				{
					printf("瀵规柟鏈湪绾縗n");
				}
				
				break;
			case 11: //鎺ユ敹韪汉鎿嶄綔鐨勮繑鍥炵粨鏋?
				if(!strcmp(RecvBuf.massage, "success"))
				{	
					printf("%s涓嬬嚎鎴愬姛锛乗n", RecvBuf.to_name);
				}
				else
				{
					printf("%s涓嶅湪绾匡紒\n", RecvBuf.to_name);
				}
				break;
			case 12://鎺ユ敹鑱婂ぉ鏈嶅姟鍣ㄧ瀛樻斁鐨勮褰?
				printf("%s\n",RecvBuf.massage);
				break;
			default: 
				break;	
				
		}
		memset(&RecvBuf, 0, sizeof(RecvBuf));
		//printf("%s\n", RecvBuf.massage);
	}
	return 0;
}
int main(int argc, char** argv)
{
	int ret;
	struct sockaddr_in server_addr;
	pthread_t tid;


	if (argc != 2)
	{
		printf("Please input IP\n");
	}

				}
	sockfd = socket(PF_INET, SOCK_STREAM, 0);
	if (-1 == sockfd)
	{
		perror("socket");
		exit(1);
	}

	memset(&server_addr, 0, sizeof(struct sockaddr_in));
	server_addr.sin_family = PF_INET;
	server_addr.sin_port = PORT;
	server_addr.sin_addr.s_addr = inet_addr(argv[1]);

	printf("姝e湪杩炴帴锛岃绋嶇瓑鈥︹€n");
	ret = connect(sockfd, (struct sockaddr *)&server_addr, sizeof(server_addr));
	if (-1 == ret)
	{
		perror("connect");
		exit(1);
	}
	ret = pthread_create(&tid, NULL, My_recv, (void *)&sockfd);
	if (0 != ret)
	{
		perror("pthread_create");
		exit(1);
	}	
	
	My_send();
	pthread_join(tid, NULL);
	return 0;
}
client.c
#include<stdio.h>
#include"client.h"


void My_send()//鍔熻兘閫夋嫨鍙戦€?
{
	int func;
	char *name;
	while(1)
	{
		Interface1();
		scanf("%d", &func);
		getchar();
		switch(func)
		{
			case 1:
				name = Log_user();
				sleep(1);
				if(user_log == 1) //鐧诲綍鎴愬姛
				{	
					User_func(name);
					sleep(1);
				}
				break;
			case 2: 
				Register();//娉ㄥ唽
				sleep(1);
				break;
			case 3:
				Log_admin();
				sleep(1);
				if(admin_log == 1)//绠$悊鍛樼櫥褰曟垚鍔?
				{
					fp = fopen("admin.txt", "a+");//鐢熸垚鏂囦欢淇濆瓨鑱婂ぉ璁板綍
					admin_func();
				}
				break;
			case 4:
				printf("leave ...\n");
				Quit();
				sleep(1);
				exit(1);
			default: 
				printf("error\n");
				break;
		}
	}
}

void Interface1()//鐣岄潰1
{
	system("clear");
	printf("*************************************\n");
	printf("*                                   *\n");
	printf("*          娆㈣繋杩涘叆鑱婂ぉ瀹?          *\n");
	printf("*             1.鐧诲綍                *\n");
	printf("*             2.娉ㄥ唽                *\n");
	printf("*             3.绠$悊鍛樼櫥褰?         *\n");
	printf("*             4.閫€鍑?               *\n");
	printf("*                                   *\n");
	printf("*************************************\n");
	printf("\n");
	printf("璇烽€夋嫨:\n");
}

void Interface2(char *name)
{
	time_t t;
	time(&t);
	system("clear");
	printf("\n");
	printf("------------------------------------------------\n");
	printf("褰撳墠鐧诲綍鐢ㄦ埛:%s\n", name);
	printf("    		 鐜板湪鏃跺埢锛?s\n", ctime(&t));
	printf("------------------------------------------------\n");
	printf("\n");
	printf("       1.鏌ョ湅鍦ㄧ嚎鐢ㄦ埛\n");
	printf("       2.绉佽亰\n");
	printf("       3.鎮勬倓璇漒n");
	printf("       4.缇ゅ彂\n");
	printf("       5.鏌ョ湅鑱婂ぉ璁板綍\n");
	printf("       6.涓嬬嚎\n");
	printf("       7.甯姪\n");
	printf("\n");
	printf("璇烽€夋嫨:\n");
}

void admin_face()
{
	time_t t;
	time(&t);
	system("clear");
	printf("-----------------------------------------------\n");
	printf("灏婃暚鐨勭鐞嗗憳澶уぇ浣犲ソ锛?         \n");
	printf(" 		     鐜板湪鏃跺埢锛?s\n", ctime(&t));
	printf("-----------------------------------------------\n");
	printf("\n");
	printf("1.鏌ョ湅鍦ㄧ嚎鐢ㄦ埛锛?.绂佽█锛?.瑙i櫎绂佽█锛?4.韪汉锛?.鏌ョ湅鎵€鏈変汉鐨勮亰澶╄褰曪紱6.涓嬬嚎\n");
	printf("\n");
	printf("璇烽€夋嫨:\n");
	
}

void User_func(char *name)//鐢ㄦ埛鍔熻兘閫夋嫨鍙戦€?
{
	int ret, func, flag;
	char *to_name;
	struct infor SendBuf;
	char buf[200] = {0};
	to_name = (char *)malloc(20*sizeof(char));
	while(1)
	{
		Interface2(name);
		scanf("%d", &func);
		getchar();
		switch(func)
		{	
			case 1: //鏌ョ湅鍦ㄧ嚎浜烘暟
				SendBuf.flag = 4;
				ret = send(sockfd, &SendBuf, sizeof(SendBuf), 0);
				memset(&SendBuf, 0, sizeof(SendBuf));
				printf("Enter any key to continue\n");
				getchar();
				break;
			case 2://绉佽亰
				to_name = Chat(name);
				flag = 6;
				sleep(1);
				system("clear");
				printf("To: %s\n", to_name);
				break;
			case 3://鎮勬倓璇?
				to_name = Chat(name);
				flag = 7;
				sleep(1);
				system("clear");
				printf("To: %s\n", to_name);
				break;
			case 4://缇ゅ彂
				system("clear");
				flag = 8;
				strcpy(to_name, "allpeople");
				fd = 1;
				break;
			case 5://鏌ョ湅鑱婂ぉ璁板綍
				fseek(fp, 0, SEEK_SET);
				while(fread((void *)buf,1,sizeof(buf),fp))
				{
					printf("%s\n", buf);
					memset(buf, 0, strlen(buf));
				}
				printf("Enter any key to continue\n");
				getchar();
				break;
			case 6://涓嬬嚎
				SendBuf.flag = 11;
				strcpy(SendBuf.to_name, name);
				ret = send(sockfd, &SendBuf, sizeof(SendBuf), 0);
				fclose(fp);//鍏抽棴鑱婂ぉ璁板綍鏂囦欢
				user_log = 0;// 鐧诲綍鎴愬姛鐨勬爣蹇楃疆0
				sleep(1);
				return;
			case 7:// 鏌ョ湅琛ㄦ儏鍜屽父鐢ㄨ
				Show_help();
				printf("Enter any key to continue\n");
				getchar();
			default: 
				break;
		}
		if(fd > 0)	//杩斿洖鐨勫鎺ュ瓧
		{
			Send_massage(name, to_name, flag);//寰幆鍙戦€佹秷鎭?
		}
	}
}

void admin_func()
{
	int ret, func;
	struct infor SendBuf;

	strcpy(SendBuf.name, "admin");
	while(1)
	{
		admin_face();
		scanf("%d", &func);
		getchar();
		switch(func)
		{	
			case 1: //鏌ョ湅鍦ㄧ嚎浜烘暟
				SendBuf.flag = 4;
				ret = send(sockfd, &SendBuf, sizeof(SendBuf), 0);
				printf("Enter any key to continue\n");
				getchar();
				break;
			case 2://绂佽█
				SendBuf.flag = 9;
				printf("璇疯緭鍏ヨ绂佽█鐨勭敤鎴凤細\n");
				scanf("%s", SendBuf.to_name);
				getchar();
				ret = send(sockfd, &SendBuf, sizeof(SendBuf), 0);
				printf("Enter any key to continue\n");
				getchar();
				break;
			case 3://瑙i櫎绂佽█
				SendBuf.flag = 10;
				printf("璇疯緭鍏ヨ瑙i櫎绂佽█鐨勭敤鎴凤細\n");
				scanf("%s", SendBuf.to_name);
				getchar();
				ret = send(sockfd, &SendBuf, sizeof(SendBuf), 0);
				printf("Enter any key to continue\n");
				getchar();
				break;
			case 4://韪汉
				SendBuf.flag = 11;
				printf("璇疯緭鍏ヨ韪㈢殑鐢ㄦ埛锛歕n");
				scanf("%s", SendBuf.to_name);
				getchar();
				ret = send(sockfd, &SendBuf, sizeof(SendBuf), 0);
				printf("Enter any key to continue\n");
				getchar();
				break;
			case 5://鏌ョ湅鎵€鏈夎亰澶╄褰?
				SendBuf.flag = 12;
				ret = send(sockfd, &SendBuf, sizeof(SendBuf), 0);
				sleep(2);
				printf("Enter any key to continue\n");
				getchar();
				break;
			case 6://涓嬬嚎
				fclose(fp);//鍏抽棴鑱婂ぉ璁板綍鏂囦欢
				admin_log = 0;//admin鐧诲綍鎴愬姛鐨勬爣蹇楃疆0
				SendBuf.flag = 11;
				strcpy(SendBuf.to_name, "admin");
				ret = send(sockfd, &SendBuf, sizeof(SendBuf), 0);
				sleep(1);
				return;
			default:
				break;
		}
	}	
}

int Log_admin()//绠$悊鍛樼櫥褰?
{
	int ret;
	struct infor user;
	strcpy(user.name, "admin");
	printf("璇疯緭鍏ュ瘑鐮侊細\n");
	scanf("%s", user.passwd);
	user.flag = 3;
	ret = send(sockfd, (void *)&user, sizeof(user), 0);// 鍙戦€佺櫥褰曚俊鎭?
	if (-1 == ret)
	{
		perror("send");
		exit(1);
	}	
	return SUCCESS;
}
char *Log_user()//鐧诲綍
{
	int ret;	
	struct infor user;
	char *name;
	name = (char *)malloc(sizeof(char) * 20);
	printf("璇疯緭鍏ョ敤鎴峰悕:\n");
	scanf("%s", user.name);
	while(strlen(user.name) > 12)
	{
		printf("鐢ㄦ埛鍚嶉敊璇紝 璇烽噸杈擄細\n");
		scanf("%s", user.name);
	}
	strcpy(name, user.name);

	printf("璇疯緭鍏ュ瘑鐮?\n");
	scanf("%s", user.passwd);
	while(strlen(user.passwd) > 12)
	{
		printf("瀵嗙爜閿欒锛岃閲嶈緭锛歕n");
		scanf("%s", user.passwd);
	}
	user.flag = 1;
	ret = send(sockfd, (void *)&user, sizeof(user), 0);// 鍙戦€佺櫥褰曚俊鎭?
	if (-1 == ret)
	{
		perror("send");
		exit(1);
	}

	printf("姝e湪鐧诲綍...\n");
	return name;
}

int Register() // 娉ㄥ唽
{
	char passwd2[13] = {0};
	struct infor user;
	int ret;
	do
	{
		printf("璇疯緭鍏ョ敤鎴峰悕锛?0瀛椾互鍐咃級:\n");
		//memset(user->name, 0, strlen((user->name));
		scanf("%s", user.name);
		getchar();
	}while(strlen(user.name) > 20);
	while(1)
	{
		printf("璇疯緭鍏ュ瘑鐮侊紙12瀛椾互鍐咃級:\n");
		//memset(user->passwd, 0,strlen(user->passwd));
		scanf("%s", user.passwd);
		getchar();
		printf("璇峰啀娆¤緭鍏ュ瘑鐮侊細\n");
		scanf("%s",passwd2);
		getchar();
		if((strlen(user.passwd) == 0) || (strlen(user.passwd) > 12) ||(strcmp(user.passwd, passwd2)))
		{
			printf("passwd error!\n");
		}
		else
		{
			break;
		}
	}
	user.flag = 2;
	
	ret = send(sockfd, (void *)&user, sizeof(user), 0);
	if (-1 == ret)
	{
		perror("send2");
		exit(1);
	}

	printf("姝e湪娉ㄥ唽...\n");
	return SUCCESS;

}

int Quit()//瀹㈡埛鏈洪€€鍑?
{
	struct infor user;
	int ret;
	user.flag = 12;
	ret = send(sockfd, &user, sizeof(user), 0);
	if (-1 == ret)
	{
		perror("send3");
		exit(1);
	}
	return SUCCESS;
}


char *Chat(char *name)//鍙戦€佽亰澶╄姹?
{
	int ret;
	struct infor SendBuf;
	char *to_name;
	to_name = (char *)malloc(sizeof(char) * 20);
	
	printf("浣犺鍜岃皝绉佽亰锛焅n");
	scanf("%s", SendBuf.to_name);
	getchar();
	SendBuf.flag = 5;
	strcpy(SendBuf.name, name);
	ret = send(sockfd, &SendBuf, sizeof(SendBuf), 0);
	strcpy(to_name, SendBuf.to_name);
	return to_name;
}

int Send_massage(char *name, char *to_name, int flag)//鍙戦€佽亰澶╁唴瀹?
{
	int ret;
	char buf[200] = {0};
	struct infor SendBuf;
	time_t t;
	
	strcpy(SendBuf.name, name);
	strcpy(SendBuf.to_name, to_name);
	SendBuf.flag = flag;
	printf("\t\t\t\t\t\t杈撳叆'end' 閫€鍑篭n");
	
	while (1)
	{	
		scanf("%s", SendBuf.massage);
		Expression(SendBuf.massage);//琛ㄦ儏鏇挎崲
		Commom_word(SendBuf.massage);//甯哥敤璇浛鎹?
		if(!strcmp(SendBuf.massage, "end"))
		{
			fd = -1;
			break;
		}
		SendBuf.fd = fd;
		//	printf("fdsend = %d\n", fd);
		//	printf("sendflag=%d\n", SendBuf.flag);
		ret = send(sockfd, &SendBuf, sizeof(SendBuf), 0);
		if (-1 == ret)
		{
			perror("send");
			exit(1);
		}
		time(&t);//鑾峰彇鏃堕棿鎴?
		sprintf(buf, "%s 浣犲 %s璇达細%s", ctime(&t), SendBuf.to_name, SendBuf.massage);
		ret = fwrite((void *)buf, 1, sizeof(buf), fp);
		memset(buf, 0, strlen(buf));
		memset(&SendBuf.massage, 0, sizeof(SendBuf.massage));
	}
	return SUCCESS;
}

void Expression(char *msg)
{
	if(!strcmp(msg, ":)"))
	{
		sprintf(msg, "鎴戝仛浜嗕釜绗戣劯");
	}
	if(!strcmp(msg, "鏅?))
	{
		sprintf(msg, "@_@");
	}
	if(!strcmp(msg, "姹?))
	{
		sprintf(msg, "-_-|||");
	}
	if(!strcmp(msg, "--"))
	{
		sprintf(msg, "鏃犺-_-~");
	}
	if(!strcmp(msg, "zz"))
	{
		sprintf(msg, "鎴戣鐫¤浜唞zZ");
	}
}

void Commom_word(char *msg)
{
	int i, j;
	char com[100] = {0};
	char tmp[100] = {0};
	if(msg[0] == '/')
	{
		for(i = 1; i < strlen(msg); i++)
		{
			if(msg[i] != '/')
			{
				com[i-1] = msg[i]; 
			}
			else
				break;
		}
		for(j = 0; j < strlen(msg); i++, j++)
		{
			if(msg[i] != '\0')
			{
				tmp[j] = msg[i];
			}
			else
				break;
		}
		if(!strcmp(tmp, "/welcome"))
		{
			strcat(com, "鍚屽,娆㈣繋鏉ュ埌鎴戜滑鐨勮亰澶╁鍝?");
		}
		if(!strcmp(tmp, "/eat"))
		{
			strcat(com, "鍚屽,浣犲悆杩囬キ浜嗗悧?");
		}
		memset(msg, 0, sizeof(msg));
		strcpy(msg, com);
	}
	else
		return;
}

void Show_help()
{
	system("clear");
	printf(":)           ----------------->>  鎴戝仛浜嗕竴涓瑧鑴竆n");
	printf("鏅?          ----------------->>  @_@\n");
	printf("姹?          ----------------->>  -_-|||\n");
	printf("--           ----------------->>  鏃犺-_-~\n");
	printf("zz           ----------------->>  鎴戣鐫¤浜唞ZZ\n");
	printf("/xxx/welcome ----------------->>  xxx鍚屽锛屾杩庢潵鍒版垜浠殑鑱婂ぉ瀹?\n");
	printf("/xxx/eat     ----------------->>  xxx鍚屽锛屼綘鍚冭繃楗簡鍚?\n");
}




猜你喜欢

转载自blog.csdn.net/costeeer/article/details/79140920