今天是项目开始的第二周了,写的比较慢,临近期末学校的考试,答辩比较多。
目前基本实现了聊天室的功能,老师要求用select写,没办法不会用,先用线程来写,后面还会用UDP还有select在写一遍。
今天整理了一下思路大致如下:
1.客户端要登陆服务器才能执行各种功能,首先需要建立套接字,然后让服务器和客户端能连接起来。
2.服务器这边我用的线程,主程序用来监听客户端的连接请求,线程就用来处理连接之后的请求操作,这都比较简单。
3.客户端连接上之后可以向服务器发送操作请求。
具体子模块如下:
注册模块:
客户端这边的注册部分我这样处理的,注册还涉及不到其他客户端的互发消息,所以不需要开线程,要注意什么时候需要线程。
首先客户端这边需要给服务器发送消息告诉服务器你要注册了 可以设置结构体成员cmd = reg;然后依次输入注册信息,将整个结构体发送给服务器。
服务器这边接到信息读cmd 进入注册模块,将注册信息存入数据库,这里可以在user表中设置账号为主键,就不会出现账号重复了,数据库这边上课没听,百度时才知道。存好之后将存出结果返回给客户端,大体上可以这样返回:1数据库打开时出错,2.账号重复导致的出错。
登陆模块:
客户端这边就比较麻烦了,需要建线程,因为你登陆之后,一方面你需要给服务器发送操作请求另一方面你需要接受信息,服务器的信息或者其他客户端的消息。这是才需要建立线程。登陆,你肯定需要输入账号还有密码,将结构体发送给服务器。根据服务器发来的信息来执行操作。
服务器这边需要接受信息然后去log函数执行,将用户信息和数据库里面的信息作对比,对比结果发送给客户端。
登陆之后可以完成私聊,相对来说前面的程序没问题了,后面的私聊,群聊都不是很难,今天先写这么多。上传一下现在的程序,只是一个半成品,存在bug。
服务器部分:
/*****************************************************
> File name: TcpNet.h
> Author: Fang Wen Qian
> 日期: 2017-12-20 00:17
*****************************************************/
#ifndef TCPNET_H_
#define TCPNET_H_
#include <sys/types.h>
#include <sys/socket.h>
#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <arpa/inet.h>
#include <pthread.h>
#include <stdlib.h>
#include <sqlite3.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <time.h>
#include <netinet/in.h>
#define PORT 8888
#define sqlexec_failure -1 //数据库操作失败
#define sqlopen_failure -2 //数据库打开失败
#define log_failure -3 //登录失败
#define reg 1 //注册
#define log 2 //登录
#define reg_success 3 //注册成功
#define log_exist 4 //在别出登录
#define common_user 5 //普通用户登录
#define Admin_user 6 //管理员登录
#define quit 10 //退出聊天室回到登录界面
#define online 7 //查看当前在线人数
#define gchat 8 //群聊
#define pchat 9 //私聊
#define confirm 55 //确认文件传输对象
#define change 66 //修改密码
#define deluser 88 //注销
#define Accept 9006 //用户接受文件
#define refuse 9005 //用户不接受文件
#define choose 9007 //处理文件传输
#define complete 9008 //文件传输完成
#define silent 9011 //处理禁言
#define delsilent 9012 //解除禁言
#define kick 9013 //踢人
// 协议
struct Msg
{
char msg[1024]; // 消息内容 (密码)
int cmd; // 消息类型
int num; // 在线人数
int state; // 禁言
char filename[50]; // 保存文件名
char toname[20]; // 接收者姓名
char fromname[20]; // 发送者姓名
int sig; // 用户状态(0:管理员、1:普通用户、2:被禁言)
};
extern sqlite3 *ppdb;
int init_socket();
int MyAccept(int listen_sockfd);
void *MyRecv(void *arg);
void del_reg(int client_sockfd,struct Msg *msg);
void del_log(int client_sockfd,struct Msg *msg);
void user_do(int client_sockfd);
void del_online(int client_sockf