基于Linux系统的tcp协议的即时通信系统(聊天室)

这个聊天室完成了一些基础功能私聊、群聊、文件传送等基础功能,可以添加表情符号等其他功能。

头文件中的名称的定义可以换成枚举形式,会更加方便一点,我脑抽了就不改了。有空再完善代码规范和功能。


myhead.h

#ifndef _MYHEAD_H_
#define _MYHEAD_H_

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


#define BUFFSIZE 50
#define MYPORT 6656
#define MYADDR "192.168.1.200"

/**功能选择**/
#define REG                  1
#define LOGIN                2
#define PRIVATE_CHAT         3
#define GROUP_CHAT           4
#define VIEW_FRIENDS         5
#define CORRECT_PIN_NUMBER   6
#define ADMINI_PRIVILEGE     7
#define SEND_OFFLINE_MSG     8
#define SEND_FILE            9
#define SIGN                 10
#define OFF_LINE             11
#define VIEW_USER_MSG        26
#define BECOME_VIP           39           //成为VIP

/**登陆注册**/
#define REG_SUCCESS          12
#define REG_FAIL             13
#define LOGIN_SUCCESS        14
#define LOGIN_FAIL           15
#define LOGIN_EXIT           16
/**创建链表**/
#define CREATE_NODE          17
/************/
#define PRIVATE_SUCCESS      18
#define PRIVATE_FAIL         19
#define GROUP_SUCCESS        20
#define VIEW_FRIENDS_SUCCESS 21
#define CORRECT_SUCCESS      22
#define CORRECT_FAIL         23
#define CORRECT_OLD          24           //用户原密码输入错误
#define OFF_LINE_SUCCESS     27
#define OFF_LINE_FAIL        28
/**权限**/
#define BAN                  29           //禁言
#define REMOVE               30           //解禁
#define KICK				 31			  //踢人
#define BAN_USER             32           //返回给被禁言的用户
#define REMOVE_USER          33           //返回给被解禁的用户
#define KICK_FAIL            34
#define BEEN_KICK            35
#define NO_POWER             36           //没有vip权限
#define SIGN_SUCCESS         37           
#define SEND_SUCCESS         38           //发送离线消息成功
#define VIP_SUCCESS          42
//#define BECOME_VIP           39           //成为VIP
#define SHOW_INFO            43
/**文件**/
#define FILE_SUCCESS         40
#define FILE_FAIL            41

typedef struct users        //用户信息:链表
{
	//struct regist *user;
	
	char username[20];      //用户名
	int clientfd;
	int power;              //1:禁言,0:未禁言
	struct users *next;
}user;

typedef struct regist       //注册
{
	int flag;               //注册登录标志符	
	int vip;                //会员用户          为1时具有会员权限,为0没有
	char username[20];      //用户名
	char password[20];      //密码
	char new_passwd1[20];   //新密码
	char new_passwd2[20];   //新密码验证
	char file[1024];        //文件
	char filename[20];      //文件名
	char sign[50];          //个性签名
//	int friend_num;         //好友数
//	int group_num;          //群组数
	char offline_msg[500];  //离线消息
	int action;		        //通过action表明是什么命令;
	char fromname[20];
	char toname[20];
	char time[20];          //时间
	
	char msg[500];          //消息内容
}client;


char my_getch()
{
	char temp = 0;
	temp = getchar();
	
}

#endif

server.c

#include "myhead.h"//server

void *read_msg_server(void *argc);
void register_client(int clientfd);
void login_client(int clientfd);
void private_chat(int clientfd);

sqlite3 *db = NULL;
char *errmsg = NULL;
char **result = NULL;
char sql[1024] = {0};

struct users *head = NULL;                    //创建用户信息的头结点

user userbuff;
client clientrecv;

int main()
{
	int socketfd = 0;
	int clientfd = 0;
	int ret = 0;
	
	struct sockaddr_in server_addr = {0};
	struct sockaddr_in client_addr = {0};
	
	socklen_t len = sizeof(struct sockaddr);
	pthread_t th;
	
	char recvbuff[20] = {0};
	int recvcnt = 0;
	
	char sendbuff[20] = {0};
	int sendcnt = 0;
	
	
	head = (struct users*)malloc(sizeof(struct users));
	if(head == NULL)
	{
		printf("malloc error\n");
	}
	//head->next = NULL;

	ret = sqlite3_open("chat.db",&db);         //建数据库
	if(ret != SQLITE_OK)
	{
		printf("数据库打开失败!");
	}

	sqlite3_exec(db,"create table account(username text primary key,password text,vip INTEGER,sign text,offline_msg text);",NULL,NULL,&errmsg);                                   //建注册信息表
	
	socketfd = socket(AF_INET,SOCK_STREAM,0);  //1.调用socket创建套接字
	if(socketfd == -1)
	{
		perror("socket");
		return -1;
	}
	printf("socket success...\n");  
	
	bzero(&server_addr,sizeof(server_addr));   //2.绑定:==》地址族,端口号,IP地址;下面就是赋值操作!
	server_addr.sin_family = AF_INET;
	server_addr.sin_port = htons(MYPORT);
	server_addr.sin_addr.s_addr = inet_addr(MYADDR);
	
	ret = bind(socketfd,(struct sockaddr *)&server_addr,sizeof(server_addr));
	if(ret == -1)
	{
		perror("bind");
		return -1;
	}
	printf("bind success...\n");
	
	ret = listen(socketfd,10);
	if(ret == -1)
	{
		perror("listen");
		return -1;
	}
	printf("listen success...\n");
	
	while(1)
	{
		clientfd = accept(socketfd,(struct sockaddr *)&client_addr,&len);
		if(clientfd == -1)
		{
			perror("accept");
			return -1;
		}
		printf("accept success... ");
		
		if(pthread_create(&th,NULL,read_msg_server,&clientfd) == -1)
		{
			perror("pthread_create");
			return -1;
		}
		pthread_detach(th);
		
	}
//	close(socketfd);
	sqlite3_free_table(result);
	slqite3_close(db);
	return 0;
}

void *read_msg_server(void *argc)
{
	struct users *p = head;
	int clientfd = *((int *)argc);		
	printf("read_msg_server:clientfd = %d\n",clientfd);
	
	int readcnt = 0;
	int writecnt = 0;

	while(1)
	{
		int login_flag = 0;
		memset(&clientrecv,0,sizeof(client));
		readcnt = read(clientfd,&clientrecv,sizeof(client));
		if(readcnt == -1)
		{
			perror("read_msg_client:read");
			return 0;
		}
		
		switch(clientrecv.action)
		{
			case 1:     //注册
			{
				register_client(clientfd);
				break;
			}
			case 2:     //登录
			{
				//login_client(clientfd);
				int i = 0;
				int j = 0;
				int nrow = 0; //行
				int ncolumn = 0; //列

				int flag = 0;
				int ret = 0;
				int readcnt =0;
				
				ret = sqlite3_get_table(db,"select * from account",&result,&nrow,&ncolumn,&errmsg);
				for(i = 1; i <= nrow; i++)
				{
					for(j = 0; j < ncolumn; j++)
					{
						if(strcmp(clientrecv.username,result[i*ncolumn]) == 0 && strcmp(clientrecv.password,result[i*ncolumn+ 1]) == 0)
						{
							flag = 1;  
							//strcpy(buff,clientrecv.username);
						}
					}
				}
				

				p = head;
				while(p->next != NULL)
				{	
					p = p->next;
					if(strcmp(p->username,clientrecv.username) == 0)
					{
						clientrecv.flag = LOGIN_EXIT;        //该用户已登录
						write(clientfd,&clientrecv,sizeof(client));
					}	
				}
				
				if(flag == 0)        //登录失败
				{
					clientrecv.flag = LOGIN_FAIL;
					write(clientfd,&clientrecv,sizeof(client));

				}
				else if(flag == 1)   //登录成功
				{
					clientrecv.flag = LOGIN_SUCCESS;
					write(clientfd,&clientrecv,sizeof(client));
				
					struct users *new = (struct users *)malloc(sizeof(struct users));
					strcpy(new->username,clientrecv.username);
					new->clientfd = clientfd;
					/*************************权限状态需要从数据库中读取**********************************/
					new->power = 0;   //未禁言状态            
					if(new == NULL)
					{
						printf("malloc error!\n");
						//return NULL;
					}
				/*	p = head;
					while(p->next != NULL)  //p不是尾结点
					{
						p = p->next;
					}
					*/p->next = new;
					new->next = NULL;
					//bzero(p,sizeof(struct users));
					
				}
				break;
			}
			case 3:                 //私聊
			{
				//private_chat(clientfd);
				
				p = head;
				int temp = 0;
				while(p->next !=NULL)
				{
					p = p->next;
					if(strcmp(p->username,clientrecv.toname) == 0)                                //存在该好友
					{
						temp = 1;
						//clientfd = p->clientfd;
						clientrecv.flag = PRIVATE_SUCCESS;
						//printf("m\n");
						printf("testing!!!\n");
						printf("%s(%d)send to%s(%d)",clientrecv.fromname,clientfd,clientrecv.toname,p->clientfd);
						write(p->clientfd,&clientrecv,sizeof(client));                            //发送给好友
						break;
					}
				}
				if(temp == 0)
				{
					clientrecv.flag = PRIVATE_FAIL;                                               //查无此人,回复给用户 
					write(clientfd,&clientrecv,sizeof(client));          
				
  • 9
    点赞
  • 33
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值