Linux下局域网通信软件(聊天室,附源码)

1、UDP_chatroom.h

/***************************************************
File name: UDP_chatroom.h
Author:刘磊
Data:2021.1.23
Description:聊天室头文件
***************************************************/

#ifndef _CHATROOM_H_
#define _CHATROOM_H_

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

/*********************注册登录**********************************/  
#define REG             1         //注册  
#define LOG             2         //登录  
#define FORGET          3         //忘记密码  
#define EXIT            4         //退出  
#define EXISTING_ACC    5         //账号已存在  
#define LOGGED_ACC      6         //账号已登录  
#define ERROR           7         //账号或密码错误  
#define LOG_SUCCESS     8         //登录成功  
#define REG_SUCCESS     9         //注册成功  
#define Exit            10        //下线  
/***************************************************************/  

/******************聊天室功能***********************************/  
#define private_chat    11        //私聊  
#define group_chat      12        //群聊  
#define group_result    13        //群聊接受  
#define file_transfer   14        //文件传输  
#define online          15        //查看在线人数  
#define expression      16        //表情  
#define phrases         17        //常用语  
#define motto           18        //个性签名  
#define motto_change    19        //更改个性签名  
#define like            20        //点赞  
#define Vip             21        //开会员  
#define Shutup          22        //禁言  
#define lifted          23        //解禁  
#define kick            24        //踢人  
/***************************************************************/  


/****************服务器返回结果*********************************/  
#define VIP_SUCCESS         25          //开会员成功  
#define SHUTUP_SUCCESS      26          //禁言成功  
#define SEND_SUCCESS        27          //发送成功  
#define SEND_FAILED         28          //操作失败
#define KICK_SUCCESS        30          //踢人成功  
#define LIKE_SUCCESS        31          //点赞成功  
#define CHANGE_SUCCESS      32          //更改个性签名成功  
#define RECVFILE_SUCCESS    33          //接受文件成功
#define SENDFILE_SUCCESS    34          //发送文件成功
/***************************************************************/  

#endif




2、UDP_server.c

/*File name: UDP_server.c
Author:刘磊
Data:2021.1.23
Description:聊天软件服务器端
***************************************************/

#include "UDP_chatroom.h"

#define PORT 8888


typedef struct info
{
   
    char username[20];              //用户名
    char account[20];               //账号
    char passwd[20];                //密码
    char from_name[20];             //发信人
    char to_name[20];               //收信人
    char moto[30];                  //个性签名
    char online_name[20][20];       //在线人名
    int  online_num;                //在线人数
    int  cmd;                       //提取操作符  
    int  vip;                       //会员标志   
    int  likes;                     //点赞数
    int  result;                    //返回操作结果 
    char msg[1024];                 //发送、接收消息    
    char e_s;                       //确认发送的表情
    char p_s;                       //确认发送的常用语  
    char file_name[50];             //文件名
    char Ftp[2048];                 //文件传输
}Info;

typedef struct node
{
   
    struct sockaddr_in client_addr;
    char name[20];
    char account[20];
    struct node *next;
}Node, *LinkList;
struct sockaddr_in client_addr;

Info SendBuf;
Info RecvBuf;
sqlite3 *ppdb = NULL;           //数据库
LinkList head = NULL;           //在线用户
int sockfd;         
int ret;


//注册
void deal_reg(struct sockaddr_in temp_addr)                                     
{
     
    char sql[200] = {
   0};     
    char *errmsg = NULL;
    sprintf(sql, "insert into chatroom(username, account, passwd, likes, vip, moto) values('%s','%s','%s','%d','%d', '%s')",RecvBuf.username, RecvBuf.account, RecvBuf.passwd, RecvBuf.likes, RecvBuf.vip, RecvBuf.moto);     
    ret = sqlite3_exec(ppdb, sql, NULL, NULL, &errmsg);  
    if(ret != SQLITE_OK)  
    {
     
        perror("sqlite3_exec2");
        SendBuf.result = EXISTING_ACC;

        ret = sendto(sockfd, &SendBuf, sizeof(SendBuf), 0, (struct sockaddr *)&temp_addr, sizeof(temp_addr));
        if (ret < 0)
        {
   
            perror("sendto_server_log");
            exit(1);
        }
        return;  
    }  

    SendBuf.result = REG_SUCCESS;
    printf("注册信息:用户名:%s \t 账号:%s \t 密码:%s\n", RecvBuf.username, RecvBuf.account, RecvBuf.passwd);
    ret = sendto(sockfd, &SendBuf, sizeof(SendBuf), 0, (struct sockaddr *)&temp_addr, sizeof(temp_addr));
    if (ret < 0)
    {
   
        perror("sendto_server_register");
        exit(1);
    }              
    bzero(&SendBuf, sizeof(SendBuf));
}

//登入
void deal_log(struct sockaddr_in temp_addr)
{
   
	char **Result = NULL;
	int nRow;
	int nColumn;
	int ret;
	char sql[200] = {
   0};

	sprintf(sql, "select username, passwd, likes, vip, moto from chatroom where account = '%s' and passwd = '%s'", RecvBuf.account,RecvBuf.passwd);
	ret = sqlite3_get_table(ppdb, sql, &Result, &nRow, &nColumn, NULL);
	if(ret != SQLITE_OK)
	{
   
		perror("sqlite3_get_table_deal_log");
		exit(1);
	}

	if(1 == nRow)
	{
   
		LinkList tmp = head->next;
		while(tmp != head)
		{
   
			if(!strcmp(tmp->account, RecvBuf.account))
			{
   
				SendBuf.result =LOGGED_ACC;

				ret = sendto(sockfd, &SendBuf, sizeof(SendBuf), 0, (struct sockaddr *)&temp_addr, sizeof(temp_addr));
				if(ret < 0)
				{
   
					perror("sendto_server_log");
					exit(1);
				}
				return;
			}
			tmp = tmp->next;
		}
		SendBuf.result = LOG_SUCCESS;

		LinkList p = (LinkList)malloc(sizeof(Node));
		if(p == NULL)
		{
   
			printf("malloc error!\n");
			return;
		}
		strcpy(p->account, RecvBuf.account);
		strcpy(p->name, Result[5]);
		strcpy(SendBuf.username,Result[5]);
		SendBuf.vip = *(Result[8]) - 48;
		SendBuf.likes = *(Result[7]) - 48;
		strcpy(SendBuf.moto, Result[9]);
		p->client_addr.sin_family = temp_addr.sin_family;
		p->client_addr.sin_port = temp_addr.sin_port;
		p->client_addr.sin_addr.s_addr = temp_addr.sin_addr.s_addr;

		printf("%s 上线!\n",Result[5]);
		printf("登录信息:用户:%s\t帐号:%s\t密码:%s\t端口号:%d\n",SendBuf.username,p->account, RecvBuf.passwd, p->client_addr.sin_port);
		
		p->next = head->next;
		head->next = p;
	}

	else
	{
   
		SendBuf.result = ERROR;
	}

	ret = sendto(sockfd, &SendBuf, sizeof(SendBuf), 0, (struct sockaddr *)&temp_addr, sizeof(temp_addr));
	if(ret < 0)
	{
   
		perror("sendto_server_log");
		exit(1);
	}
}




//私聊
int deal_private(struct sockaddr_in temp_addr)
{
   
    int flag = 0;
    LinkList tmp = head->next;
    while(tmp != head)
    {
   
        if(!strcmp(tmp->name,RecvBuf.to_name))
        {
   
            flag = 1;
            strcpy(SendBuf.msg, RecvBuf.msg);
            strcpy(SendBuf.from_name,RecvBuf.username);

            SendBuf.result = private_chat;

            ret = sendto(sockfd, &SendBuf, sizeof(SendBuf), 0, (struct sockaddr *)&tmp->client_addr, sizeof(tmp->client_addr));
            if(ret == -1)
            {
   
                perror("sendto_pchat");
                exit(1);
            }
            break;
        }
        tmp=tmp->next;
    }

     if(flag)
    {
   
        SendBuf.result = SEND_SUCCESS;
        ret = sendto(sockfd, &SendBuf, sizeof(SendBuf), 0, (struct sockaddr *)&temp_addr, sizeof(temp_addr));
        if(ret == -1)
        {
   
            perror("sendto_success");
            exit(1);
        }       
    }
    else
    {
   
        SendBuf.result = SEND_FAILED;
        ret = sendto(sockfd, &SendBuf, sizeof(SendBuf), 0, (struct sockaddr *)&temp_addr, sizeof(temp_addr));
        if(ret == -1)
        {
   
            perror("sendto_failure");
            exit(1);
        }
    }
}   

//群聊
int deal_group(struct sockaddr_in temp_addr)
{
   
    int flag = 0;
    LinkList tmp = head->next;

    while (tmp != head)
    {
   
        if (tmp->client_addr.sin_port != temp_addr.sin_port)
        {
   
            flag = 1;

            SendBuf.result = group_chat;


            strcpy(SendBuf.from_name, RecvBuf.username);
            strcpy(SendBuf.msg, RecvBuf.msg);

            ret = sendto(sockfd, &SendBuf, sizeof(SendBuf), 0, (struct sockaddr *)&tmp->client_addr, sizeof(tmp->client_addr));
            if (ret < 0)
            {
   
                perror("sendto_group_chat");
                exit(1);
            }
        }
        tmp = tmp->next;
    }
    if (flag)
    {
   
        SendBuf.result = SEND_SUCCESS;
        ret = sendto(sockfd, &SendBuf, sizeof(SendBuf), 0, (struct sockaddr *)&temp_addr, sizeof(temp_addr));
        if (ret < 0)
        {
   
            perror("sendto_group_chat_success");
            exit(1);
        }
    }
    else 
    {
   
        SendBuf.result = SEND_FAILED;
        ret = sendto(sockfd, &SendBuf, sizeof(SendBuf), 0, (struct sockaddr *)&temp_addr, sizeof(temp_addr));
        if (ret < 0)
        {
   
            perror("sendto_group_chat_failure");
            exit(1);
        }
    }
}

//查看在线人数
int deal_online(struct sockaddr_in temp_addr)
{
   
    int i = 0;
    SendBuf.online_num = 0;
    LinkList tmp = head->next;
    while(tmp != head)
    {
   
        SendBuf.online_num++;
        strcpy(SendBuf.online_name[i],tmp->name);
        i++;
        tmp = tmp->next;
    }
    SendBuf.result = online;

    ret = sendto(sockfd, &SendBuf, sizeof(SendBuf), 0, (struct sockaddr *)&temp_addr, sizeof(temp_addr));
    if(ret == -1)
    {
   
        perror("sendto_online");
    }
}

//点赞
int deal_like(struct sockaddr_in temp_addr)
{
   
    char *errmsg = NULL;  
    char **Result = NULL;  
    int  nRow;  
    int  nColumn;  
    char sql[100];  

    sprintf(sql, "select likes from chatroom where username = '%s'", RecvBuf.to_name);
    ret = sqlite3_get_table(ppdb, sql, &Result, &nRow, &nColumn, &errmsg);  
    if(ret != SQLITE_OK)  
    {
     
        printf("select fail:%d(%s)\n", ret, errmsg);  
        return -1;  
    }  

    if(nRow == 1)  
    {
      
        sprintf(sql, "update chatroom set likes = %d where username = '%s'", *(Result[1]) - 47, RecvBuf.to_name);  
        ret = sqlite3_exec(ppdb, sql, NULL, NULL, &errmsg);  
        if(ret != SQLITE_OK)  
        {
     
            printf("update fail:%d(%s)\n", ret, errmsg);  
            return ;  
        }  

        LinkList tmp = head->next;

        while(tmp != head)              //遍历数据库,找到用户
        {
      
            if(strcmp(tmp->name, RecvBuf.to_name) == 0)  
            {
     
                SendBuf.likes = *(Result[1]) - 47;  
                SendBuf.result = like;  
                strcpy(SendBuf.from_name,RecvBuf.username);  

                ret = sendto(sockfd, &SendBuf, sizeof(SendBuf), 0, (struct sockaddr *)&tmp->client_addr, sizeof(tmp->client_addr));
                if(ret == -1)
                {
   
                    perror("sendto_like");
                }
                break;
            }
            tmp = tmp->next;
        }

        SendBuf.result = LIKE_SUCCESS;          
        ret = sendto(sockfd, &SendBuf, sizeof(SendBuf), 0, (struct sockaddr *)&temp_addr, sizeof(temp_addr));
        if(ret == -1)
        {
   
            perror("sendto_like_suuess");
        }   
    }
    else  
    {
     
        SendBuf.result = SEND_FAILED;  
        ret = sendto(sockfd, &SendBuf, sizeof(SendBuf), 0, (struct sockaddr *)&temp_addr, sizeof(temp_addr));
        if(ret == -1)
        {
   
            perror("sendto_like_failed");
        }       
    }
}

//修改个性签名
int deal_moto_change(struct sockaddr_in temp_addr)
{
   
	char *errmsg = NULL;
	char **Result = NULL;
	int nRow;
	int nColumn;
	char sql[100];
		
		sprintf(sql, "update chatroom set moto = '%s' where username = '%s'", RecvBuf.moto, RecvBuf.username);
		ret = sqlite3_exec(ppdb, sql, NULL, NULL, &errmsg);
		if(ret != SQLITE_OK)
		{
   
			printf("update fail:%d(%s)\n", ret, errmsg);
			return;
		}
		LinkList tmp = head->next;
		while(tmp != head)
		{
   
			if(strcmp(tmp->name, RecvBuf.username) == 0)
			{
   
				sprintf(sql, "select moto from chatroom where username = '%s'", RecvBuf.username);
				ret = sqlite3_get_table(ppdb, sql, &Result, &nRow, &nColumn, &errmsg);
				if(ret != SQLITE_OK)
				{
   
					printf("select fail:%d(%s)\n", ret, errmsg);
					return -1;
				}
				strcpy(SendBuf.moto, Result[1]);
				SendBuf.result = motto_change;
				strcpy(SendBuf.from_name, RecvBuf.username);

				ret = sendto(sockfd, &SendBuf, sizeof(SendBuf), 0, (struct sockaddr *)&tmp->client_addr,sizeof(tmp->client_addr));
				if(ret == -1)
				{
   
					perror("sendto_moto");
				}
				break;
			}
			tmp = tmp->next;
		}
		SendBuf.result = CHANGE_SUCCESS;
		ret = sendto(sockfd, &SendBuf, sizeof(SendBuf), 0, (struct sockaddr *)&temp_addr, sizeof(temp_addr));
		if(ret == -1)
		{
   
			perror("sendto_moto_succuess");
		}
}

//发送表情(群发)
int deal_expression(struct sockaddr_in temp_addr)
{
   
    int flag = 0;
    LinkList tmp = head->next;
    while (tmp != head)
    {
   
        if (tmp->client_addr.sin_port != temp_addr.sin_port)
        {
   
            flag = 1;

            SendBuf.result = expression;
            strcpy(SendBuf.from_name, RecvBuf.username);
            SendBuf.e_s = RecvBuf.e_s;
            ret = sendto(sockfd, &SendBuf, sizeof(SendBuf), 0, (struct sockaddr *)&tmp->client_addr, sizeof(tmp->client_addr));
            if (ret < 0)
            {
   
                perror("sendto_face");
                exit(1)
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值