select 实现网络聊天室功能 (客户端)

客户端:

ChatRoom.h

#ifndef  _CHATROOM_H_H
#define  _CHATROOM_H_H

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <sqlite3.h>
#include <pthread.h>
#include <time.h>
#include <sys/stat.h>
#include <fcntl.h>



#define  TRUE     1
#define  FALSE    2
#define  SUCCESS  3
#define  FAILURE  4
#define  PORT     8888

#define  REGISTER               100
#define  REG_SUCCESS            101
#define  LOGIN                  102
#define  LOG_SUCCESS            103
#define  LOG_FAILURE            104
#define  OnLine                 105
#define  NoOnLine               106
#define  Online                 107
#define  PrivateChat            108
#define  OFFLINE                109
#define  GroupChat              110
#define  ChatVip                111
#define  ShutUp                 112
#define  NoShutup               113
#define  SHUTUP                 114
#define  IsChatVip              115
#define  NoChatVip              116
#define  IsGroupShutup          117
#define  NoGroupShutup          118
#define  Kick                   119
#define  KickSuccess            120    
#define  KickFailure            121
#define  KickOk                 122
#define  KickNoOk               123
#define  Expression             124

struct user
{
	char id[20];
	char password[20];
	char username[20];
	char toname[20];
	int Tofd;                             //文件描述符
    int cmd;
    char online[20][20]	;
    int n;	                              //记录在线人数
	char buf[100];                        //聊天内容 
	int vip ;
    int speak;
	int find;
	char ep;                             

};

struct linknode
{
	struct user User;
	struct linknode *next;
};



void Register(struct user *U);
void Login(struct user *U);
int isOnLine(struct linknode *List, struct user *User);
void ListInsert(struct linknode *list, struct user *User);
void TraverList(struct linknode*list, struct user *User);
void ChatRoom(int chatfd, struct user recvbuf, struct user USER);
void DeleteList(struct linknode *list, struct user *User);
void TraverId(struct linknode *list, struct user User, sqlite3 *db);
void TraverFriend(struct linknode *list, struct user User, sqlite3 *db);
void gettime();
void DealVip(struct user User, sqlite3 *db);
void Shut_up(struct user User, sqlite3 *db);
void DealKick(struct linknode *list, struct user User, sqlite3 *db);
char *nowtime();
void ExpressionShow();
void des_ep(struct user User);

#endif
		


Client.c

#include <stdio.h>
#include "ChatRoom.h"




int main()
{
	int sockfd,ret;
	struct sockaddr_in server_addr;
    
	struct user User = {0};
	char choice[20] = {0};
	struct user RecvBuf = {0};
	Show();

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

	memset(&server_addr, 0, sizeof(server_addr));
	server_addr.sin_family = PF_INET;
	server_addr.sin_port = htons(PORT);
	server_addr.sin_addr.s_addr = inet_addr("192.168.0.128");

	printf("Start Connecting...\n");
	ret = connect(sockfd, (struct sockaddr *)&server_addr, sizeof(server_addr));
	if (-1 == ret)
	{
		perror("connect");
		exit(1);
	}
	while(1)
	{
		
		PrintInfo();
		scanf("%s", choice);
		switch(atoi(&choice[0]))
		{
			case 1:
			
			Register(&User);
			
			ret = send(sockfd, &User, sizeof(User), 0);
			
			if (-1 == ret)
			{
				perror("send");
				exit(1);
			}

			ret = recv(sockfd, &RecvBuf, sizeof(RecvBuf), 0);
			if (-1 == ret)
			{
				perror("recv");
				exit(1);
			}

			if (RecvBuf.cmd == REG_SUCCESS)
			{
				printf("注册成功!\n");
			}
			break;
			case 2:
			Login(&User);
			
			ret = send(sockfd, &User, sizeof(User), 0 ); 
			if (-1 == ret)
			{
				perror("send");
				exit(1);
			}

			ret = recv(sockfd, &RecvBuf, sizeof(RecvBuf), 0);
			if (-1 == ret)
			{
				perror("recv");
				exit(1);
			}
			if (RecvBuf.cmd == LOG_SUCCESS)
			{
				printf("登录成功!\n");

				ChatRoom(sockfd, RecvBuf, User);
			}
			else if (RecvBuf.cmd == LOGIN)
			{
				printf("登录失败,您还未注册或密码有误!\n");
			}
			else if (RecvBuf.cmd == OnLine)
			{
				printf("帐号已经登录,请下线!\n");
			}
			break;

			case 3:
			exit(0);
		
			default :
			printf("请输入1-3之间的选择!\n");
			break;
		}
	}

	return 0;
}


TestChat.c

#include <stdio.h>
#include "ChatRoom.h"

pthread_t tid;

void *Recv(void *arg)
{
	struct user RecvBuf = {0};
	int ret, i, oldtype;
	int fd;
	char tmp[1024] = {0};
	char tmp_filename[200] = {0};

	pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, &oldtype);

	while(1)
	{
		ret = recv(*(int *)arg, &RecvBuf, sizeof(RecvBuf), 0);
		if (-1 == ret)
		{
			perror("recv");
			exit(1);
		}


		switch(RecvBuf.cmd)
		{
			case Online:
				for (i = 0; i < RecvBuf.n; i++)
				printf("%s在线\n", RecvBuf.online[i]);
				printf("你的好友有%d人在线\n", RecvBuf.n);
				memset(&RecvBuf, 0, sizeof(RecvBuf));
				break;
			case PrivateChat:
				if (RecvBuf.find == NoShutup)
				{
					gettime();
					printf("您的好友%s: %s\n", RecvBuf.username, RecvBuf.buf);
				}
				else if (RecvBuf.find == SHUTUP)
				{
					printf("对不起,大侠您已经被管理员禁言了!\n");
				}
				sprintf(tmp, "%s %s\n", nowtime(), RecvBuf.buf);
				sprintf(tmp_filename, "%s 与 %s的聊天记录.txt", RecvBuf.toname, RecvBuf.username);

				fd = open(tmp_filename, O_RDWR | O_CREAT | O_APPEND, 0777);
				if (-1 == fd)
				{
					perror("open");
					exit(1);
				}
				ret = write(fd, tmp, strlen(tmp));
				if (-1 == ret)
				{
					perror("write");
					exit(1);
				}
				close(fd);
				memset(tmp, 0, sizeof(tmp));
				memset(tmp_filename, 0, sizeof(tmp_filename));
				memset(&RecvBuf, 0, sizeof(RecvBuf));
				break;
			case GroupChat:
				if (RecvBuf.find == NoGroupShutup)
				{
					gettime();
					printf("您收到来自好友%s的一个群发消息: %s \n", RecvBuf.username, RecvBuf. buf);
				}
				else
				{
					printf("对不起,大侠您不能和好友们说话了!\n");
				}
				memset(&RecvBuf, 0, sizeof(RecvBuf));
				break;

			case ChatVip:
				if (RecvBuf.vip == 1)
				{
					printf("大侠恭喜您成为会员!\n");	
				}
				else
				{
					printf("大侠您已经注册过会员了!\n");
				}
				memset(&RecvBuf, 0, sizeof(RecvBuf));
				break;
			case Kick:
				if (RecvBuf.find == KickFailure)
				{
					printf("对不起,您还不是会员,无法踢人!\n");
				}
				else if (RecvBuf.find == KickSuccess)
				{
					printf("大侠您已经成功将他踢走!\n");
				}
				else if (RecvBuf.find == KickOk)
				{
					printf("对不起,您被管理员给强制下线了,期待下次能遇见您!\n");
					exit(0);
				}
				else if (RecvBuf.find == KickNoOk)
				{
					printf("对不起,无法进行操作, 您踢的对象未上线或用户名错误!\n");
				}
				memset(&RecvBuf, 0, sizeof(RecvBuf));
				break;
			case ShutUp:
				{
					if (RecvBuf.find == IsChatVip)
					{
						printf("恭喜您已经使他闭嘴了!\n");
					}
					else if(RecvBuf.find == NoChatVip)
					{
						printf("大侠您还不是会员哦,无法进行禁言功能!\n");
					}
					memset(&RecvBuf, 0, sizeof(RecvBuf));
					break;
				}
			case Expression:
				{
					if (RecvBuf.find == SHUTUP)
					{
						printf("大侠您被禁言了,无法发送表情!\n");
					}
					else if(RecvBuf.find == NoShutup)
					{
						 des_ep(RecvBuf);
					}
					memset(&RecvBuf, 0, sizeof(RecvBuf));
					break;
				}
			
		}


	}
}

void Show()
{
	system("clear");
	printf("\t\t\t\t***********************************************************************\n\n\n\n");
	printf("\t\t\t\t			欢迎您来到大侠聊天室                          \n\n\n\n");
	printf("\t\t\t\t************************************************************************\n\n\n\n");
	sleep(2);
	system("clear");
}

void PrintInfo()
{
	printf("\t\t\t\t\t\t************************************************************************\n\n");
	printf("\t\t\t\t\t\t                               大侠聊天室                               \n");
	printf("\t\t\t\t\t\t            1.注册用户                           2.登录用户             \n");
	printf("\t\t\t\t\t\t                                                                        \n");
	printf("\t\t\t\t\t\t            3.退出                                                      \n");
	printf("\t\t\t\t\t\t************************************************************************\n\n");
	printf("请输入您的选择\n");
}

void ChatShow()
{
	printf("\t\t\t\t\t\t***********************************************************************\n\n");
	printf("\t\t\t\t\t\t                               大侠聊天室                              \n\n\n");
	printf("\t\t\t\t\t\t                             1.查看在线用户                            \n");
	printf("\t\t\t\t\t\t                             2.私聊                                    \n");
	printf("\t\t\t\t\t\t                             3.群聊                                    \n");
	printf("\t\t\t\t\t\t                             4.查看聊天记录                            \n");
	printf("\t\t\t\t\t\t                             5.创建管理员                              \n");
	printf("\t\t\t\t\t\t                             6.踢人                                    \n");
	printf("\t\t\t\t\t\t                             7.禁言                                    \n");
	printf("\t\t\t\t\t\t                             8.发送表情                                \n");
	printf("\t\t\t\t\t\t                             9.下线                                    \n");
	printf("\t\t\t\t\t\t***********************************************************************\n\n");
	printf("请输入您的选择\n");
}

void ExpressionShow()
{
	printf("\t\t\t\t\t\t*************************************************************************\n\n");
	printf("\t\t\t\t\t\t                          1 开心       (^_^)                               \n");
	printf("\t\t\t\t\t\t                          2.生气       = || =                              \n");
	printf("\t\t\t\t\t\t                          3.不屑       (-v -)                              \n");
	printf("\t\t\t\t\t\t                          4.为你加油   *\(^_^)/*                           \n");
	printf("\t\t\t\t\t\t                          5.哭泣       (T_T)                               \n");
	printf("\t\t\t\t\t\t                          6.不满       (~|~)                               \n");
	printf("\t\t\t\t\t\t                          7.竖起大拇指 b(^v^)d                             \n");
	printf("\t\t\t\t\t\t                          8.亲亲        >5<                                \n");
	printf("\t\t\t\t\t\t*************************************************************************\n\n");
	printf("请输入您想发送的表情\n");
}

void des_ep(struct user User)
{
	char ex[20];
	switch(User.ep)
	{
		case '1':
			{
				strcpy(ex, "(^_^)");
				printf("好友%s 发送了一个表情给您 %s\n", User.username, ex);
				break;
			}
		case '2':
			{
				strcpy(ex, "= || =");
				printf("好友%s 发送了一个表情给您 %s\n", User.username, ex);
				break;
			}
		case '3':
			{
				strcpy(ex, "(-v -)");
				printf("好友%s 发送了一个表情给您 %s\n", User.username, ex);
				break;
			}
		case '4':
			{
				strcpy(ex, "*\(^_^)/*");
				printf("好友%s 发送了一个表情给您 %s\n", User.username, ex);
				break;
			}
		case '5':
			{
				strcpy(ex, "T_T");
				printf("好友%s 发送了一个表情给您 %s\n", User.username, ex);
				break;
			}
		case '6':
			{
				strcpy(ex,"(~|~)");
				printf("好友%s 发送了一个表情给您 %s\n", User.username, ex);
				break;
			}
		case '7':
			{
				strcpy(ex, "b(^v^)d");
				printf("好友%s 发送了一个表情给您 %s\n", User.username, ex);
				break;

			}
		case '8':
			{
				strcpy(ex, ">5<");
				printf("好友%s 发送了一个表情给您 %s\n", User.username, ex);
				break;
			}



	}
}

void gettime()
{
	time_t rawtime;
	struct tm * timeinfo;
	time(&rawtime);                              //获取时间  以秒计  从1970年1月1日起算
	timeinfo = localtime(&rawtime);
	printf("%s", asctime(timeinfo));             //asctime()  转为标准ASCII时间格式
}

char *nowtime()                                 //指针用于聊天记录
{
	time_t rawtime;
	struct tm*timeinfo;
	time(&rawtime);
	timeinfo = localtime(&rawtime);
	return asctime(timeinfo);
}
void Register(struct user *U)
{
	char temp[20] = {0};
    U->cmd = REGISTER;

	printf("开始注册!\n");
	printf("请注册您的帐号:\n");
	scanf("%s",U->id);
	printf("请注册您的密码:\n");
	scanf("%s",U->password);
	strcpy(temp, U->password);
	printf("请再次确认您的密码:\n");
	scanf("%s",U->password);
	while ((strcmp(temp, U->password)))
	{
		printf("输入密码出错,请重新输入正确密码:\n");
		scanf("%s",U->password);
	}
	printf("请注册您的用户名:\n");
	scanf("%s",U->username);
	U->vip = 0;
	U->speak = 0;
}

void Login(struct user *U)
{
	U->cmd = LOGIN;

	printf("请登录您的帐号!\n");
	scanf("%s",U->id);
	printf("请登录您的密码!\n");
	scanf("%s",U->password);
}


void ChatRoom(int chatfd, struct user recvbuf, struct user USER)
{
	int ret;
	int fd;
	char choice[20] = {0};
	char pay[10] = {0};
	char tmp[1024] = {0};
	char tmp_filename[200] = {0};
	char records[100] = {0};
	char e[10] = {0};

	ret = pthread_create(&tid, NULL, Recv, (void *)&chatfd);       //创建线程
	if (0 != ret)
	{
		perror("pthread_create1");
		exit(1);
	}
    while(1)
	{
		ChatShow();
        scanf("%s",choice);
		switch(atoi(&choice[0]))
		{
			case 1:
				USER.cmd = Online;
			
				ret = send(chatfd, &USER, sizeof(USER), 0);
				if (-1 == ret)
				{
					perror("send");
					exit(1);
				}
				sleep(1);
			/*	ret = recv(chatfd,&recvbuf, sizeof(recvbuf), 0);
				if (-1 == ret)
				{
					perror("recv");
					exit(1);
				}
				for(i = 0; i < recvbuf.n; i++)
				printf("%s 在线\n",recvbuf.online[i]);                //打印在线好友用户名
				printf("你的好友有%d人在线\n",recvbuf.n);*/             
		
				break;
			case 2:
				USER.cmd = PrivateChat;
				strcpy(USER.username, recvbuf.username);

				printf("大侠您想与谁说悄悄话:\n");
				scanf("%s",USER.toname);
				printf("大侠您想和他说什么?\n");
				scanf("%s", USER.buf);

				ret = send(chatfd, &USER, sizeof(USER), 0);
				if (-1 == ret)
				{
					perror("send");
					exit(1);
				}

				sprintf(tmp, "%s %s\n", nowtime(), USER.buf);
				sprintf(tmp_filename, "%s 与 %s的聊天记录.txt", USER.username, USER.toname);
				fd = open(tmp_filename, O_RDWR | O_CREAT | O_APPEND, 0777);
				if (-1 == fd)
				{
					perror("open");
					exit(1);
				}
				ret = write(fd, tmp, strlen(tmp));
				if (-1 == ret)
				{
					perror("write");
					exit(1);
				}
				close(fd);
				memset(tmp, 0, sizeof(tmp));
				memset(tmp_filename, 0, sizeof(tmp_filename));
				sleep(1);
				break;

			case 3:
				USER.cmd = GroupChat;
				printf("大侠您想跟好友们说什么?\n");
				scanf("%s", USER.buf);

				ret = send(chatfd, &USER, sizeof(USER), 0);
				if (-1 == ret)
				{
					perror("send");
					exit(1);
				}
				sleep(1);
				break;
			case 4:
				strcpy(USER.username, recvbuf.username);
				printf("大侠您想查看与谁的聊天记录?\n");
				scanf("%s", USER.toname);
				sprintf(tmp_filename, "%s 与 %s的聊天记录.txt", USER.username, USER.toname);
				fd = open(tmp_filename, O_RDONLY, 0777);
				if (-1 == fd)
				{
					perror("open");
					exit(1);
				}
				
				while(ret = read(fd, records, sizeof(records) - 1) != 0)
				{
					printf("%s", records);
					memset(records, 0, sizeof(records));
				}
				close(fd);

				
				break;
			case 5:
				
				USER.cmd = ChatVip;
				strcpy(USER.username, recvbuf.username);
				printf("大侠您想成为永久荣耀会员吗? (y/n)\n");
				scanf("%s",pay);

				if ('y' == pay[0])
				{
					ret = send(chatfd, &USER, sizeof(USER), 0);
					if (-1 == ret)
					{
						perror("send");
						exit(1);
					}
				}
				sleep(2);
				break;
			case 6:
				USER.cmd = Kick;
				strcpy(USER.username, recvbuf.username);
				printf("大侠您想踢走谁呢?\n");
				scanf("%s", USER.toname);

				ret = send(chatfd, &USER, sizeof(USER), 0);
				if (-1 == ret)
				{
					perror("send");
					exit(1);
				}
				sleep(2);
				break;

			case 7:
				USER.cmd = ShutUp;
				strcpy(USER.username, recvbuf.username);
				printf("大侠您想让谁闭嘴?\n");
				scanf("%s", USER.toname);

				ret = send(chatfd, &USER, sizeof(USER), 0);
				if (-1 == ret)
				{
					perror("send");
					exit(1);
				}
				sleep(2); 
				break;
			case 8:
				USER.cmd = Expression;
				strcpy(USER.username, recvbuf.username);
				printf("大侠您想发送表情给哪位好友呢?\n");
				scanf("%s", USER.toname);
				ExpressionShow();
				scanf("%s",e);
				USER.ep = e[0];

				ret = send(chatfd, &USER, sizeof(USER), 0);
				if (-1 == ret)
				{
					perror("send");
					exit(1);
				}
				sleep(1);
				break;

            case 9:
				USER.cmd = OFFLINE;
				strcpy(USER.id, recvbuf.id);
			
				ret = send(chatfd, &USER, sizeof(USER), 0);
				if (-1 == ret)
				{
					perror("send");  
					exit(1);
				}
				printf("下线成功,期待下次与大侠见面!\n");
				sleep(1);
				exit(0);
				default:
				printf("Unkown choice");
			}

		
	}
			
	

}







  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值