客户端头文件
#ifndef CLIENT_H
#define CLIENT_H
#include <string.h>
#include <stdlib.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <time.h>
#include <unistd.h>
#define FAILURE 10000
#define SUCCESS 10001
#define FALSE 10002
#define TRUE 10003
#define PORT 8888
struct sockaddr_in server_addr;
enum Enum
{
REG,
LOGIN,
PRIVATE,
GROUP,
};
typedef enum Enum ENUM;
struct user
{
char petname[32];
char age[32] ;
char sex[32] ;
char key[32];
int cmd;
int member;
char buf[32];
};
typedef struct user User;
struct judge
{
int cmd;
char buf[32];
char petname[32];
char t2[128];
};
typedef struct judge Judge;
struct info
{
int ToFd;
char petname[32];
char ptr[64];
};
typedef struct info InFo;
void menu();
void menu2();
void Register(int sockfd); //实现用户注册
int Login(int sockfd); //登录
void showfriend(int sockfd, char ptr[32]); //显示在线好友
int exitlogin(int sockfd, char ptr[32]); //退出登录
int chatprivate(int sockfd, char ptr[32]); //私聊
void deposit(int sockfd, char ptr[32]); //充值会员
void checkrecord(int sockfd, char ptr[32]); //查看与某人的私聊记录
void key(int sockfd); //修改密码
void groupchat(int sockfd, int L, char ptr[32]); //发起群聊
void cancel(int sockfd, char ptr[32]); //注销账号
void groupcheck(int sockfd); //查看群聊记录
void praise(int sockfd); //点赞好友
int convert(int sockfd, char ptr[32]); //传输文件
char *MyGetch(); //实现密码不回显
#endif
客户端自定义功能函数
/**************************************************************
> File Name: ChatClient.c
> Author: yangxuan
> Mail: 2503327051@qq.com
> Created Time: 2018年08月23日 星期四 17时39分14秒
**************************************************************/
#include <stdio.h>
#include "Client.h"
#include <stdlib.h>
#include <string.h>
#include <termios.h>
#define MAX_PASSWD_LEN 6
//全局变量
char str[32] = {0};
char petname[32] = {0}; //记下注册的用户名
int ret; //用来接收多个函数执行的返回值
//菜单, 显示该通讯录所能实现的功能
void menu()
{
system("clear");
printf("*********************************\n");
printf("********1,注册 ******************\n");
printf("********2, 登录 ******************\n");
printf("********3, 查看在线好友 ***********\n");
printf("********4, 私聊 ******************\n");
printf("********5, 群聊 ******************\n");
printf("********6, 查看群聊信息 ***********\n");
printf("********7, 查看私聊记录 ***********\n");
printf("********8, 注销帐号****************\n");
printf("********9, 充值会员****************\n");
printf("********10, 点赞 ******************\n");
printf("********11, 退出登录 **************\n");
printf("********12, 传输文件 **************\n");
printf("*******13,查看接受文件 ************\n");
printf("******请选择你想要的功能 ***********\n");
printf("***********************************\n");
}
/*
作者:杨宣
函数原型:void Register(int sockfd)
函数解释:自定义函数, 函数名 :Register 带有一个int型的参数,函数返回值为void型的
函数功能:实现用户注册帐号功能 ,若密码输入不一致,提示重新输入
*/
void Register(int sockfd)
{
system("clear"); //执行之前先清屏
User SendInfo; //先定义结构体中间变量,保存用户的注册信息,信息录好后再将其拷贝到结构体中
char age[32] = {0};
char sex[32] = {0};
char key[32] = {0};
char key2[32] = {0};
char buf[32] = {0};
printf("请给自己取个昵称!\n");
scanf("%s", petname);
printf("请输入你的年龄!\n");
scanf("%s", age);
printf("请输入您的性别!\n");
scanf("%s", sex);
printf("请输入六位密码!\n");
getchar(); //一定要加这句,清空缓冲区的回车键,下面输密码也要加
strcpy(key, MyGetch());
printf("请再次输入密码!\n");
strcpy(key2, MyGetch());
while(strcmp(key, key2) != 0)
{
memset(key, 0, sizeof(key));
memset(key2, 0, sizeof(key2));
printf("您两次密码输入不一致, 请重新输入密码!\n");
printf("请输入六位密码!\n");
strcpy(key, MyGetch());
printf("请再次输入密码!\n");
strcpy(key2, MyGetch());
}
strcpy(SendInfo.petname, petname);
strcpy(SendInfo.age, age);
strcpy(SendInfo.sex, sex);
strcpy(SendInfo.key, key);
SendInfo.cmd = 1;
ret = send(sockfd, &SendInfo, sizeof(SendInfo), 0);
if(ret == -1)
{
perror("send3");
}
}
/*
作者:杨宣
函数原型:void key(int sockfd)
函数解释:自定义函数, 函数名 :key 函数带有一个int型的参数, 函数返回值为void型的
函数功能:用户注册好后设置密保
*/
void key(int sockfd)
{
User SendInfo;
memset(&SendInfo, 0, sizeof(SendInfo));
SendInfo.cmd = 15;
strcpy(SendInfo.petname, petname); //注册好后设置密保
printf("请设置密保问题,方便日后找回密码!\n");
printf("爷爷的爸爸叫什么?\n");
scanf("%s", SendInfo.age);
printf("爸爸的爷爷叫什么?\n");
scanf("%s", SendInfo.sex);
printf("爷爷的爸爸叫什么?\n");
scanf("%s", SendInfo.key);
ret = send(sockfd, &SendInfo, sizeof(SendInfo), 0);
if(ret == -1)
{
perror("send3");
}
}
/*
作者:杨宣
函数原型:int Login(int sockfd)
函数解释:自定义函数, 函数名 :Login 函数带有一个int型的参数, 函数返回值为void型的
函数功能:用户登录
*/
int Login(int sockfd)
{
system("clear"); //每次调用的时候都清屏,提升界面视觉化体验感
int ret;
char buf[32] = {0};
User U;
char petname[32] = {0};
char key[32] = {0};
printf("请输入昵称!\n");
scanf("%s", petname);
printf("请输入密码!\n");
getchar();
strcpy(key, MyGetch());
strcpy(U.petname, petname);
strcpy(U.key, key);
U.cmd = 2;
ret = send(sockfd, &U, sizeof(U), 0);
if(ret == -1)
{
perror("send2");
}
return FAILURE;
}
/*
作者:杨宣
函数原型:void showfriend(int sockfd, char ptr[32])
函数说明:自定义函数, 函数名 :showfriend 函数带有一个int型的参数, 函数返回值为void型的
函数功能:查询在线好友
*/
void showfriend(int sockfd, char ptr[32])
{
system("clear");
User U;
U.cmd = 3;
int ret;
char buf[32] = {0};
strcpy(U.petname, ptr);
ret = send(sockfd, &U, sizeof(U), 0);
if(ret == -1)
{
perror("sendf");
}
}
/*
作者:杨宣
函数原型:int exitlogin(int sockfd, char ptr[32])
函数说明:自定义函数, 函数名 :exitlogin 函数带有一个int型的参数, 函数返回值为void型的
函数功能:发送用户想要退出登录信息给服务端
*/
int exitlogin(int sockfd, char ptr[32])
{
system("clear");
char buf[32] = {0};
printf("确认退出登录吗?, y or n\n"); //再次确认是否要退出
scanf("%s", buf);
User U;
U.cmd = 11;
if(strcmp(buf, "y") == 0)
{
strcpy(U.petname, ptr);
printf("ptr%s\n", U.petname);
ret = send(sockfd, &U, sizeof(U), 0);
if(ret == -1)
{
perror("sendlogin");
}
}
else
{
printf("谢谢你留下来, 快找好友唠嗑吧!\n");
sleep(2);
return SUCCESS;
}
return FAILURE;
}
/*
作者:杨宣
函数原型:int chatprivate(int sockfd, char ptr[32])
函数说明:自定义函数, 函数名 :chatprivate 函数带有一个int型的参数, 一个char型的数组, 函数返回值为void型的
参1:发送线程的文件描述符 参2:私聊发起人的昵称
函数功能:向服务器发送私聊申请
*/
int chatprivate(int sockfd, char ptr[32])
{
system("clear");
User U;
char buf[32] = {0};
printf("请选择私聊对象!\n");
scanf("%s", U.petname);
printf("输入发送的话\n");
scanf("%s", U.age);
//strcpy(U.petname, buf);
strcpy(U.buf, ptr);
U.cmd = 4;
ret = send(sockfd, &U, sizeof(U), 0);
if(ret == -1)
{
perror("sendpri");
}
return 0;
}
/*
作者:杨宣
函数原型:void deposit(int sockfd, char ptr[32])
函数说明:自定义函数, 函数名 :deposit 函数带有一个int型的参数, 一个char型的数组, 函数返回值为void型的
参1:发送线程的文件描述符 参2:私聊发起人的昵称
函数功能:向服务器发起 充值会员信息
*/
void deposit(int sockfd, char ptr[32])
{
system("clear");
User U;
printf("每月付费8元,可享受绿钻会员特权!\n");
printf("每月付费15元,可享受皇冠会员特权!\n");
printf("每月付费20元,可享受王者特权!\n");
printf("***请选择你想要享受哪种特权****\n");
printf("1, 绿钻, 2,皇冠 3,王者 \n");
scanf("%d", &U.member);
U.cmd = 9;
strcpy(U.petname, ptr);
ret = send(sockfd, &U, sizeof(U), 0);
if(ret == -1)
{
perror("sendmem");
}
}
/*
作者:杨宣
函数原型:void praise(int sockfd)
函数说明:自定义函数, 函数名 :praise 函数带有一个int型的参数, 函数返回值为void型的
函数功能:发送用户想要点赞好友的信息给客户端
*/
void praise(int sockfd)
{
system("clear");
User U;
printf("请选择你想点赞的好友名\n");
scanf("%s", U.petname);
U.cmd = 10;
ret = send(sockfd, &U, sizeof(U), 0);
if(ret == -1)
{
perror("sendprise");
}
}
/*
作者:杨宣
函数原型:void checkrecord(int sockfd, char ptr[32])
函数说明:自定义函数, 函数名 :checkrecord 函数带有一个int型的参数, 一个char型的数组, 函数返回值为void型的
参1:发送线程的文件描述符 参2:私聊发起人的昵称
函数功能:向服务器发起 查询与某人私聊记录 请求
*/
void checkrecord(int sockfd, char ptr[32])
{
system("clear");
User U;
printf("你想查看与哪个好友的聊天记录\n");
scanf("%s", U.petname);
U.cmd = 7;
strcpy(U.buf, ptr);
ret = send(sockfd, &U, sizeof(U), 0);
if(ret == -1)
{
perror("sendcheck");
}
}
/*
作者:杨宣
函数原型:void groupchat(int sockfd, int L, char ptr[32])
函数说明:函数 带有两个int 型参数,一个char 型数组 返回值:void 型
函数功能:发送群聊邀请给服务器
*/
void groupchat(int sockfd, int L, char ptr[32])
{
system("clear");
User U;
//L = 0;
printf("请给群聊起个名字\n");
scanf("%s", U.sex);
while(1)
{
printf("请输入你想邀请进行群聊的好友名, 输入ok 确认邀请完毕\n");
scanf("%s", U.petname);
if(strcmp(U.petname, "ok") == 0)
{
printf("群聊邀请已发送!\n");
break;
}
U.cmd = 5;
strcpy(U.age, ptr);
ret = send(sockfd, &U, sizeof(U), 0);
if(ret == -1)
{
perror("sendgroup");
}
}
}
/*
作者:杨宣
函数原型:void cancel(int sockfd, char ptr[32])
函数说明:形参为套接字,该客户端登录账号昵称,返回值void
函数功能:注销账号
*/
void cancel(int sockfd, char ptr[32])
{
User U;
strcpy(U.petname, ptr);
U.cmd = 8;
ret = send(sockfd, &U, sizeof(U), 0);
if(ret == -1)
{
perror("send");
}
}
/*
作者:杨宣
函数原型:void groupcheck(int sockfd)
函数说明:形参为int 型的套接字
函数功能:向服务器发送查询群聊聊天记录请求
*/
void groupcheck(int sockfd)
{
User U;
printf("请输入你想查询记录的群名:\n");
scanf("%s", U.petname);
U.cmd = 6;
ret = send(sockfd, &U, sizeof(U), 0);
if(ret == -1)
{
perror("send");
}
}
/*
作者:杨宣
函数原型:int convert(int sockfd, char ptr[32])
函数说明:形参为套接字,该客户端登录账号昵称,返回值int
函数功能:发送用户想要传输文件信息给服务端
*/
int convert(int sockfd, char ptr[32])
{
User U;
FILE *fp;
Judge J;
int i = 0;
printf("请选择传输文件的对象\n");
scanf("%s", U.petname);
printf("清输入传输的文件名\n");
scanf("%s", U.buf);
fp = fopen(U.buf, "r");
if(fp == NULL)
{
printf("文件解析失败\n");
return FAILURE;
}
else
{
strcpy(U.age, ptr);
U.cmd = 23;
ret = send(sockfd, &U, sizeof(U), 0); //先将文件名和发送者发给客户端
if(ret == -1)
{
perror("send");
}
while(1)
{
memset(U.buf, 0, sizeof(U.buf)); //每次使用之前都要清空
ret = fread(U.buf, 1,sizeof(U.buf) - 1, fp); //不断的从文件中获取一个buf大小, ret为读到的字节数
if(r