学习Linux网络编程实现小项目-聊天室(2)--客户端代码

本文档详细介绍了如何在Linux环境下进行网络编程,以创建一个聊天室的客户端为例,提供了client.h和client.c两个关键文件的代码实现,帮助读者理解客户端的编程逻辑。
摘要由CSDN通过智能技术生成

封装过的出错函数可以去服务端代码里找

以下是代码实现

client.h
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <fcntl.h>
#include <errno.h>
#include <pthread.h>
#include <unistd.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <dirent.h>
#include <fcntl.h>
#include <sys/stat.h>
#include <sys/wait.h>
//#include "fcntl-linux.h"
#include <limits.h>
#include <termio.h>
#include <sys/sendfile.h>
#include "wrang.h"
#include "List.h"
#include "pthreadpool.h"



//#define SERV_ADDRESS "47.94.14.45"
//#define SERV_ADDRESS "127.0.0.1"
#define SERV_ADDRESS "192.168.30.185"
//#define SERV_ADDRESS "192.168.1.184"
#define SERV_PORT 8013

#define MAX 50
#define MAX_CHAR 300
#define SAVE 10
#define BUF 2048


#define REGISTER 1
#define LOGIN 2
#define MODIFY 3

#define ADD_FRIEND 4
#define DEL_FRIEND 5
//#define QUERY_FRIEND 6
#define PRIVATE_CHAT 7
#define VIEW_FRIEND_LIST 8
//#define SHOW_FRIEND_STATUS 9
#define VIEW_CHAT_HISTORY 10
#define SHIELD 11
#define UNSHIELD 12
#define SHOW_FRIEND 13
//#define GET_FRIEND_STATUS 14

#define CREAT_GROUP 15
#define ADD_GROUP 16
#define DEL_GROUP 17
#define WITHDRAW_GROUP 18
#define KICK 19
#define SET_GROUP_ADMIN 20
#define VIEW_ADD_GROUP 21
#define VIEW_GROUP_MEMBER 22 
#define VIEW_GROUP_RECORD 23
#define SEND_FILE 24
#define GROUP_CHAT 25

#define ADD_FRIEND_APPLY 26
#define DEL_FRIEND_APPLY 27
#define PRIVATE_CHAT_APPLY 28
#define SHIELD_APPLY 29
#define UNSHIELD_APPLY 30
#define VIEW_FRIEND_LIST_APPLY 31
//#define VIEW_FRIEND_STATUS_APPLY 32

#define CREAT_GROUP_APPLY 33
#define ADD_GROUP_APPLY 34
#define DEL_GROUP_APPLY 35
#define WITHDRAW_GROUP_APPLY 36
#define SET_GROUP_ADMIN_APPLY 37
#define KICK_APPLY 38
#define VIEW_ADD_GROUP_APPLY 39
#define VIEW_GROUP_MEMBER_APPLY 40
#define MESSAGE_RECORD 41

#define REGISTER_APPLY 42
#define LOGIN_APPLY 43
#define PRINT_APPLY 44
#define ADD_FRIEND_ACCEPT 45
#define VIEW_CHAT_HISTORY_APPLY 46
#define ADD_FRIEND_ACCEPT_APPLY 47
#define GROUP_APPLY 48
#define ADD_GROUP_ACCEPT 49
#define ADD_GROUP_ACCEPT_APPLY 50
#define VIEW_GROUP_RECORD_APPLY 51
#define GROUP_CHAT_APPLY 52
#define RECV_FILE 53
//#define REGISTER_ERROR_APPLY 54
#define EXIT 54
//#define EXIT_APPLY 55
#define RECV_APPLY 55
#define UPLOAD 56
#define DOWNLOAD 57


#define DOWNLINE 0
#define ONLINE 1
#define UNBLACK 1
#define BLACK 0

#define OWNER 1
#define ADMIN 2
#define COMMON 3

pthread_mutex_t mutex_gmb;
pthread_cond_t cond_gmb;

pthread_mutex_t mutex_msg;
pthread_cond_t cond_msg;

pthread_mutex_t mutex_login;
pthread_cond_t cond_login;

pthread_mutex_t mutex_show;
pthread_cond_t cond_show;

pthread_mutex_t mutex_add_grp;
pthread_cond_t cond_add_grp;

pthread_mutex_t mutex_gchat;
pthread_cond_t cond_gchat;

pthread_mutex_t mutex_gcord;
pthread_cond_t cond_gcord;

int cfd;

int flag_login=0;

typedef struct message
{
   
    int flag;
    int id;
    char messsge[256];
}message;


typedef struct apply_messgae
{
   
    int flag;
    int sender;
    int recver;
    int send_fd;
    int recv_fd;
    char message[256];
}apply_messgae;



typedef struct chat_message
{
   
    int flag;
    int sender;
    int recver;
    char message[256];
    //char time[30];
}Chat_message;


typedef struct box
{
   
    int flag;
    int sender;
    int recver;
    int send_fd;
    int recv_fd;
    char message[256];
    //struct box* next;
}box_t;

typedef struct box_node
{
   
    box_t data;
    struct box_node *next;
    struct box_node *prev;
}box_node_t,*box_list_t;
box_list_t head;
box_list_t fhead;



typedef struct relation_info
{
   
    int flag;
    int sender;
    int recver;
    int relation;
    char message[256];
}Relation_t;

typedef struct friend_info
{
   
    int flag;
    int send;
    int recv;
    int status;
    int relation;
    char name[MAX];

    char message[256];
}Friend_t;


typedef struct group_info
{
   
    int flag;
    int group_owner;
  
    int admin;
    char group_name[MAX];
}Group_t;


typedef struct group_leader
{
   
    int flag;
    int sender;
    int recver;
    int admin;
    char message[256];
}Group_leader;




typedef struct file
{
   
    int flag;
    int sender;
    int recver;
    int file_size;
    char file_name[100];
    char data[800];
}file_t;
int len;



typedef struct account
{
   
    int flag;
    int id;
    char name[MAX];
    char password[MAX];
    struct sockaddr_in useraddr;
  
    int online;      //1:开;0:关
    int connfd;      //链接套接字
}Account_t;

int username;
int nums=0;
void Login_menu();
void Menu();
void Friend_menu();
void Group_menu();


void Register();
void Register_apply(char* buf);
//void Register_error_apply(char* buf);

void Login();
void Login_apply(char* buf);

void Exit();
void Exit_apply(char* buf);

void Add_friend();
void Add_friend_apply(char* buf);
void Friend_box();
void Add_friend_accept_appy(char* buf);

void Del_friend();
void Del_friend_apply(char* buf);

void Shield_friend();
void Shield_friend_apply(char* buf);

void Unshield_friend();
void Unshield_friend_apply(char* buf);

void View_friend();
void View_friend_list_apply(char* buf);

void Private_chat();
void Private_chat_apply(char* buf);

void View_chat_history();
void View_chat_history_apply(char*  buf);


void Create_group();
void Create_group_apply(char* buf);

void Add_group();
void Add_group_apply(char* buf);

void Group_box();
void Group_apply(char* buf);
void Add_group_accept_apply(char* buf);

void Withdraw_group();
void Withdraw_group_apply(char* buf);
void Del_group_apply(char* buf);

void View_add_group();
void View_add_group_apply(char* buf);


void View_group_member();
void View_group_member_apply(char* buf);


void Group_chat();
void Group_chat_apply(char* buf);

void View_group_record();
void View_group_record_apply(char* buf);

void Set_group_admin();
void Set_group_admin_apply(char* buf);

void Kick();
void Kick_apply(char* buf);


void File_menu();

//void Upload();
void Send_file();
//void* Send_file(void *arg);

void Download();
//void* Recv_file(void *arg);
void Recv_file(char* buf);
void Recv_apply(char* buf);


void Send_message(int flag,char* buf);




void display(char* str);
void my_err(const char* err_string,int line);
char* Get_string(char* buf,int len);
//char getch();
int getch();
void Clear_buffer();
int Get_choice(char *choice_t);

void Init_socket();
void *Recv_pack(void* arg);
void Turn_worker_thread();
client.c
#include "client.h"
#define SIZE 100
#define MAXLEN  80 //一行显示的最多字符数
#define BUFFSIZE 32
#define BUFMAX 1024

int g_leave_len=MAXLEN; //一行剩余长度,用于输出对齐
int g_maxlen;      //存放某目录下最长文件名的长度


void Print_menu();

int Check_data(char *num);//检查输入是否为数字
int Get_choice_int(char* str);
char *Time();
void Print_apply(char* buf);
int GetPassword(char *password);
int get_choice_int(int min, int max);

void Client_list();
void Display(char* pathname);
void Display_single(char* name);


void clear_stdin();
char* get_str(char* str,size_t len);






int main()
{
   
    Init_socket();
    

    List_Init(head,box_node_t);
    List_Init(fhead,box_node_t);
    pthread_mutex_init(&mutex_login,NULL);
    pthread_cond_init(&cond_login,NULL);

    pthread_mutex_init(&mutex_add_grp,NULL);
    pthread_cond_init(&cond_add_grp,NULL);

    pthread_mutex_init(&mutex_gchat,NULL);
    pthread_cond_init(&cond_gchat,NULL);

    pthread_mutex_init(&mutex_show,NULL);
    pthread_cond_init(&cond_show,NULL);

    pthread_mutex_init(&mutex_msg,NULL);
    pthread_cond_init(&cond_msg,NULL);

    pthread_mutex_init(&mutex_gcord,NULL);
    pthread_cond_init(&cond_gcord,NULL);

    pthread_mutex_init(&mutex_gmb,NULL);
    pthread_cond_init(&cond_gmb,NULL);


    Login_menu();
    //printf("开始收包\n");
    Turn_worker_thread();
    //Menu();

    close(cfd);
}
void Init_socket()
{
   
    
    
    printf("客户端启动\n");
    struct sockaddr_in serv_addr;


    cfd=Socket(AF_INET,SOCK_STREAM,0);

    bzero(&serv_addr,sizeof(serv_addr));
    serv_addr.sin_family=AF_INET;
    serv_addr.sin_port=htons(SERV_PORT);
    inet_pton(AF_INET,SERV_ADDRESS,&serv_addr.sin_addr.s_addr);
    //serv_addr.sin_addr.s_addr=htonl(INADDR_ANY);
    Connect(cfd,(struct sockaddr*)&serv_addr,sizeof(serv_addr));

    Turn_worker_thread();

    printf("客户端启动成功!\n");

}

//密码回显
//返回值不包括'\0'
int GetPassword(char *password)
{
   
	char ch;
	int i=0;
    do
    {
   
        ch = getch();
        if(ch != '\n' && ch != '\r' && ch!=127)
        {
   
            password[i]=ch;
            printf("*");
            i++;
        }
        else if(((ch!='\n')|(ch!='\r'))&&(ch==127))
        {
   
            if(i>0)
            {
   
                i--;
                printf("\b \b");
            }
        }
    }while(ch!='\n'&&ch!='\r');
    password[i]='\0';
	return i;
}
void Register()
{
   
    Account_t register_t;
    
    char buf[BUFMAX];
    memset(buf,0,sizeof(buf));
    printf("用户名:");
    printf("[此用户名为您暂时的名字,并不是登录账号]\n");
    scanf("%s",register_t.name);
    //fgets(register_t.username,sizeof(register_t.username),stdin);
    printf("密码:");
    scanf("%s",register_t.password);
    //fgets(register_t.password,sizeof(register_t.password),stdin);
    register_t.flag=REGISTER;

    memcpy(buf,&register_t,sizeof(Account_t));

    printf("client flag:%d\n",register_t.flag);
    printf("client message:%s\n",register_t.password);
    printf("client send:%s\n",register_t.name);
    if(send(cfd,buf,sizeof(buf),0)<0)
    {
   
        my_err("send error!",__LINE__);
    }
}
void Register_apply(char* buf)
{
   
    message mes;
    memcpy(&mes,buf,sizeof(mes));

    printf("--------%s\n",mes.messsge);
    int id=mes.id;
    printf("----等会输入账号时请输入系统给您的账号\n");
    printf("您的账号是:%d\n",mes.id);
    printf(">...\n");
    printf("正在返回登录界面\n");
    usleep(1000);
    Login_menu();
    //sleep(1);
    //getchar();
}
/*void Register_error_apply(char* buf)
{
    message mes;
    printf("-----%s\n",mes.messsge);
}*/
int Check_data(char *num)
{
   
    int i;
    for(i=0;num[i];i++) 
    {
   
        if(num[i]>'9' || num[i]<'0')//只要有非数字,就返回错误
        {
   
            printf("您的输入不为数字\n");
            return 0;
        }
    }

    if(i>100)//长度超过100位,返回错误
    {
   
        printf("超出数字长度\n");
        return 0;
    }
    return 1;
}
int Get_choice_int(char* str)
{
   
    while (1)
    {
   
        scanf("%s",str);
        if (Check_data(str)==0)
        {
   
            //printf("wraning------[[[不要输入之前注册的用户名]]]\n");
            printf("输入错误,请重新输入整数\n");
        }
        else
        {
   
            printf("输入正确\n")
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值