即时通讯系统————基于TCP协议的C/S架构(Client)

本文档详细介绍了基于TCP协议的客户端部分设计,包括客户端头文件的定义,自定义功能函数的实现,以及客户端主函数的流程。通过这些内容,读者可以理解如何构建一个即时通讯系统的客户端。
摘要由CSDN通过智能技术生成

 

客户端头文件

#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
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值