基于TCP协议简易聊天室(客户端)
来源:互联网 发布:数据挖掘算法入门案例 编辑:程序博客网 时间:2024/04/27 19:42
客户端:
/*********************************************************
- File name :chat.c
* ******************************************************/
#include "../../include/net.h"
int sayto_1(int sfd)
{
Node *newnode = (Node *) malloc (sizeof(Node));
memset(newnode, 0, sizeof(Node));
/* 私聊验证 */
newnode->ack = sayto;
printf("你想发给谁\n");
scanf("%s",newnode->toname);
/* 异常处理 */
if(getchar() != '\n')
{
printf("用户名格式不正确\n");
printf("\n请重新输入指令\n");
while(getchar() != '\n')
{
continue;
}
return 0;
}
printf("你想对他说什么\n");
gets(newnode->msg);
write(sfd, newnode, sizeof(Node));
return 0;
}
int sayall_1(int sfd)
{
Node *newnode = (Node *) malloc (sizeof(Node));
memset(newnode, 0, sizeof(Node));
/* 群聊验证 */
newnode->ack = sayall;
printf("你想对他们说什么\n");
gets(newnode->msg);
write(sfd, newnode, sizeof(Node));
return 0;
}
int dis_1(int sfd)
{
Node *newnode = (Node *) malloc (sizeof(Node));
memset(newnode, 0, sizeof(Node));
newnode->ack = dis;
write(sfd, newnode, sizeof(Node));
printf("你当前在线好友为\n");
return 0;
}
int change_1(int sfd)
{
int i;
char buf[10];
char buf_1[10];
char buf_2[10];
Node *newnode = (Node *) malloc (sizeof(Node));
memset(newnode, 0, sizeof(Node));
newnode->ack = change;
memset(buf, 0, sizeof(buf));
memset(buf_1, 0, sizeof(buf_1));
memset(buf_2, 0, sizeof(buf_2));
printf("请输入你的原先密码\n");
printf("请输入修改后的密码\n");
printf(" 密码确认\n");
printf("\033[3A");
printf("\t\t\t\t");
for(i = 0; (buf[i++] = my_getch()) != '\n'; )
{
printf("*");
}
buf[i - 1] = '\0';
strcpy(newnode->password, buf);
while(1)
{
printf("\t\t\t\t");
memset(buf_1, 0, sizeof(buf_1));
for(i = 0; (buf_1[i++] = my_getch()) != '\n'; )
{
printf("*");
}
printf("\t\t\t\t");
memset(buf_2, 0, sizeof(buf_2));
for(i = 0; (buf_2[i++] = my_getch()) != '\n'; )
{
printf("*");
}
if(strcmp(buf_1,buf_2) == 0)
{
break;
}
else
{
printf("两次密码输入不相同\n");
printf("请重新输入\n");
}
}
buf_1[i - 1] = '\0';
strcpy(newnode->msg, buf_1);
printf("newnode = %s\n", newnode->msg);
write(sfd, newnode, sizeof(Node));
return 0;
}
/*********************************************************
- File name :history_recv.c
* ******************************************************/
#include "../../include/net.h"
int history_recv(Node *newnode, int flag)
{
char buf[100];
char history_msg[1024];
char *sql;
char *errmsg;
time_t time_now;
memset(buf, 0, sizeof(buf));
sprintf(buf, "create table if not exists %s(history varchar(1024));", newnode->toname);
sql = buf;
if(SQLITE_OK != sqlite3_exec(db, sql, NULL, NULL, &errmsg))
{
perror("sqlite3_exec create error!\n");
exit(0);
}
memset(history_msg, 0, sizeof(history_msg));
if(flag == MSG_RECV_ONE)
{
time(&time_now);
sprintf(history_msg, "%s%-6s对你说:%s", ctime(&time_now), newnode->name, newnode->msg);
memset(buf, 0, sizeof(buf));
sprintf(buf, "insert into %s values('%s');", newnode->toname, history_msg);
sql = buf;
printf("%s\n", sql);
if(SQLITE_OK != sqlite3_exec(db, sql, NULL, NULL, &errmsg))
{
perror("sqlite3_exec insert error!\n");
exit(0);
}
}
return 0;
}
/*********************************************************
- File name :my_getch.c
* ******************************************************/
#include <stdio.h>
#include <termios.h>
#include "../../include/net.h"
char my_getch()
{
struct termios stored_settings;
struct termios new_settings;
tcgetattr (0,&stored_settings);
new_settings = stored_settings;
new_settings.c_lflag &= (~ICANON);
new_settings.c_cc[VTIME] = 0;
new_settings.c_cc[VMIN] = 1;
tcsetattr(0,TCSANOW,&new_settings);
char ch;
ch = getchar();
putchar('\b'); //删除回显
tcsetattr(0,TCSANOW,&stored_settings); //恢复系统设置
return ch;
}
char get_choice()
{
char src[10];
while (1)
{
gets(src);
if (strcmp("reg",src) == 0)
{
return reg;
}
else if (strcmp("log",src) == 0)
{
return log;
}
else if (strcmp("sayto",src) == 0)
{
return sayto;
}
else if (strcmp("sayall",src) == 0)
{
return sayall;
}
else if (strcmp("dis",src) == 0)
{
return dis;
}
else if (strcmp("change",src) == 0)
{
return change;
}
else if(strcmp("send_file", src) == 0)
{
return send_file;
}
else if (strcmp("stop_say",src) == 0)
{
return stop_say;
}
else if (strcmp("let_say",src) == 0)
{
return let_say;
}
else if (strcmp("t_man",src) == 0)
{
return t_man;
}
else if (strcmp("quit",src) == 0)
{
return quit;
}
else
{
printf("\n请输入正确指令\n");
}
}
}
/*********************************************************
- File name :net.h
* ******************************************************/
#ifndef _NET_H_
#define _NET_H_
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <fcntl.h>
#include <unistd.h>
#include <signal.h>
#include <pthread.h>
#include <termios.h>
#include <sqlite3.h>
struct node
{
int ack;
char id[9];
char name[20];
char password[10];
char toname[20];
char msg[1024];
char file_name[100];
char file_msg[1024];
};
typedef struct node Node;
struct online
{
int sfd;
int on_flag;
int speek_flag;
char name[20];
struct online *next;
};
typedef struct online Online;
enum
{
reg = 0, // 注册
log, // 登录
sayto, // 私聊
sayall, // 群聊
dis, // 查看在线用户
change, // 修改密码
send_file, // 发送文件
stop_say, // 禁言
let_say, // 解禁
t_man, // 踢人
quit = 10, // 退出
SUCCESS, // 成功
FAILE, // 失败
sup, // 超级用户
EXIT, // 用户存在
NOT_EXIT, // 用户不存在
PASSWD_ERR, // 密码错误
SUCCESS_LOG, // 成功登录
REG_NOT_EXIT, // 注册名可用
REG_EXIT, // 注册名不可用
SUCCESS_REG = 20, // 成功注册
No_say, // 已经被禁言
Ok_say, // 你已被解禁
MSG_RECV_ONE, // 接收私聊
MSG_RECV_ALL, // 接收群聊
DIS_NAME, // 列出当前在线用户
PASSWD_SUCCESS, // 修改密码成功
RECV_FILE, // 接受文件
STOP_SAY_OK, // 禁言成功
NOT_STOP_SAY, // 并没有被禁言
LET_SAY_OK = 30, // 解禁成功
No_online, // 无其他用户在线
T_OK, // 踢人成功
YOU_OUT, // 提示用户被踢
QUIT_OK, // 成功退出
chat // 聊天界面
};
extern sqlite3 *db;
void read_msg(void *arg);
void passwd(void *arg);
char get_choice();
extern int Flag;
int change_1(int sfd);
int chat_one(int sfd);
int dis_1(int sfd);
char my_getch();
char get_choice();
int let_say_1(int sfd);
int log_1(int sfd);
void menu_start();
void menu_chat();
void menu_sup();
int reg_1(int sfd);
int sayto_1(int sfd);
int sayall_1(int sfd);
int send_1(int sfd);
int recv_file(Node *newnode);
int stop_say_1(int sfd);
int t_man_1(int sfd);
int tcp_connect(const char *ip);
int history_recv(Node *newnode, int flag);
#endif
/*********************************************************
- File name :log_reg.c
* ******************************************************/
#include "../../include/net.h"
int log_1(int sfd)
{
int i;
char buf[10];
char temp[20];
Node *newnode = (Node *) malloc (sizeof(Node));
memset(newnode, 0, sizeof(Node));
newnode->ack = log;
system("clear");
printf("+-----------------------------------+\n");
printf("| |\n");
printf("| 登录帐号 |\n");
printf("| |\n");
printf("+-----------------------------------+\n");
printf("| |\n");
printf("| |\n");
printf("| 帐 号: |\n");
printf("| |\n");
printf("| |\n");
printf("| 密 码: |\n");
printf("| |\n");
printf("| |\n");
printf("+-----------------------------------+\n");
printf("\033[8;16H ");
gets(newnode->id);
memset(temp, 0 ,sizeof(temp));
strcpy(temp, newnode->id);
for(i = 0; i < 20; i++)
{
if(temp[i] == ' ')
{
printf("\033[16;10H ");
printf("用户名不合法,请重新输入\n");
printf("\033[18;10H ");
printf(" 请按ENTER键返回\n");
while(getchar() != '\n')
{
continue;
}
return 0;
}
}
printf("\033[11;16H ");
memset(buf, 0, sizeof(buf));
for(i = 0; (buf[i++] = my_getch()) != '\n'; )
{
printf("*");
}
buf[i - 1] = '\0';
strcpy(newnode->password,buf);
/* 发送帐户信息 */
write(sfd, newnode, sizeof(Node));
return 0;
}
int reg_1(int sfd)
{
int i;
char temp[20];
char buf_1[10] = {0};
char buf_2[10] = {0};
Node *newnode = (Node *) malloc (sizeof(Node));
memset(newnode, 0, sizeof(Node));
newnode->ack = reg;
system("clear");
printf("+-----------------------------------+\n");
printf("| |\n");
printf("| 注册帐号 |\n");
printf("| |\n");
printf("+-----------------------------------+\n");
printf("| |\n");
printf("| 帐 号: |\n");
printf("| |\n");
printf("| 密 码: |\n");
printf("| |\n");
printf("| 密码确认: |\n");
printf("| |\n");
printf("+-----------------------------------+\n");
printf("\033[7;16H ");
gets(newnode->name);
memset(temp, 0 ,sizeof(temp));
strcpy(temp, newnode->name);
for(i = 0; i < 20; i++)
{
if(temp[i] == ' ')
{
printf("\033[16;10H ");
printf("用户名不合法,请重新输入\n");
printf("\033[18;10H ");
printf(" 请按ENTER键返回\n");
while(getchar() != '\n')
{
continue;
}
return 0;
}
}
while(1)
{
printf("\033[9;16H ");
memset(buf_1, 0, sizeof(buf_1));
for(i = 0; (buf_1[i++] = my_getch()) != '\n'; )
{
printf("*");
}
printf("\033[11;16H ");
memset(buf_2, 0, sizeof(buf_2));
for(i = 0; (buf_2[i++] = my_getch()) != '\n'; )
{
printf("*");
}
if(strcmp(buf_1,buf_2) == 0)
{
break;
}
else
{
printf("两次密码输入不相同\n");
printf("请重新输入\n");
}
}
buf_1[i - 1] = '\0';
strcpy(newnode->password,buf_1);
/* 发送帐户信息 */
write(sfd, newnode, sizeof(Node));
return 0;
}
/*********************************************************
- File name :main.c
* ******************************************************/
#include "../../include/net.h"
sqlite3 *db = NULL;
pthread_mutex_t mutex;
int Flag = reg;
int main(int argc, char **argv)
{
if(argc != 2)
{
printf("Usage: <IP Address>\n");
exit(-1);
}
int rc;
if(SQLITE_OK != (rc = sqlite3_open("history.db", &db)))
{
perror("sqlite3_open error!\n");
exit(0);
}
int sfd = tcp_connect(argv[1]);
char ch = '0';
pthread_t id;
pthread_create(&id, NULL, (void *)read_msg, (void *)&sfd);
while(Flag == reg)
{
system("clear");
menu_start();
if((ch = get_choice()) != quit)
{
switch(ch)
{
case log:
{
log_1(sfd);
sleep(1);
break;
}
case reg:
{
reg_1(sfd);
break;
}
default:
{
printf("start error!\n");
exit(0);
}
}
}
}
if(Flag == chat)
{
system("clear");
menu_chat();
while((ch = get_choice()) != quit)
{
if(Flag == YOU_OUT)
{
printf("请重新登录\n");
break;
}
switch(ch)
{
case sayto:
{
sayto_1(sfd);
break;
}
case sayall:
{
sayall_1(sfd);
break;
}
case dis:
{
dis_1(sfd);
break;
}
case change:
{
change_1(sfd);
break;
}
case send_file:
{
send_1(sfd);
break;
}
default:
{
printf("chat error!\n");
exit(0);
}
}
}
}
else if(Flag == sup)
{
system("clear");
menu_sup();
while((ch = get_choice()) != quit)
{
switch(ch)
{
case stop_say:
{
stop_say_1(sfd);
break;
}
case let_say:
{
let_say_1(sfd);
break;
}
case t_man:
{
t_man_1(sfd);
break;
}
default:
{
printf("sup error!\n");
exit(0);
}
}
}
}
if(ch == quit)
{
Node *newnode = (Node *) malloc (sizeof(Node));
memset(newnode, 0, sizeof(Node));
newnode->ack = quit;
write(sfd, newnode, sizeof(Node));
sleep(1);
}
return 0;
}
/*********************************************************
- File name :menu.c
* ******************************************************/
#include "../../include/net.h"
void menu_start()
{
printf("+-----------------------------------+\n");
printf("| |\n");
printf("| 欢迎使用 |\n");
printf("| V1.0 |\n");
printf("+-----------------------------------+\n");
printf("| |\n");
printf("| |\n");
printf("| 登录(log) 注册(reg) |\n");
printf("| |\n");
printf("| |\n");
printf("+-----------------------------------+\n");
}
void menu_chat()
{
printf("+-------------------------------------+\n");
printf("| |\n");
printf("| 欢迎使用 |\n");
printf("| V1.0 |\n");
printf("+-------------------------------------+\n");
printf("| |\n");
printf("| 你想和谁说悄悄话 (sayto) |\n");
printf("| 你想和大家说些什么(sayall) |\n");
printf("| 看看当前在线好友 (dis) |\n");
printf("| 修改密码 (change) |\n");
printf("| 离开吗 (quit) |\n");
printf("| |\n");
printf("+-------------------------------------+\n");
}
void menu_sup()
{
printf("+-------------------------------------+\n");
printf("| |\n");
printf("| 你是超级用户 |\n");
printf("| |\n");
printf("+-------------------------------------+\n");
printf("| |\n");
printf("| 你想禁言谁 (stop_say) |\n");
printf("| 你想解禁谁 (let_say) |\n");
printf("| 你又想将谁踢掉(t_man) |\n");
printf("| 离开吗 (quit) |\n");
printf("| |\n");
printf("+-------------------------------------+\n");
}
/*********************************************************
- File name :read_msg.c
* ******************************************************/
#include "../../include/net.h"
void read_msg(void *arg)
{
int sfd = *((int *)arg);
int nread;
Node *newnode = (Node *) malloc (sizeof(Node));
while(1)
{
memset(newnode, 0, sizeof(Node));
if((nread = read(sfd, newnode, sizeof(Node))) == 0)
{
close(sfd);
pthread_exit(NULL);
}
switch(newnode->ack)
{
case sup: //admin
{
printf("登录成功!\n");
Flag = sup;
break;
}
case EXIT:
{
printf("用户已登录,请不要重复登录\n");
break;
}
case NOT_EXIT:
{
printf("您输入的用户名不存在!\n");
printf("请重新输入!\n");
break;
}
case PASSWD_ERR:
{
printf("密码不正确,请重新输入\n");
Flag = reg;
break;
}
case SUCCESS_LOG:
{
printf("登录成功!\n");
Flag = chat;
break;
}
/******************
case REG_NOT_EXIT:
{
menu_start();
break;
}
******************/
case REG_EXIT:
{
printf("用户已存在,请重新输入\n");
Flag = reg;
break;
}
case SUCCESS_REG:
{
printf("注册成功\n");
printf("请记住你的ID: %s\n",newnode->id);
Flag = reg;
break;
}
case MSG_RECV_ONE:
{
printf("%s 悄悄对你说 %s\n",newnode->name,newnode->msg);
history_recv(newnode, MSG_RECV_ONE);
break;
}
case MSG_RECV_ALL:
{
printf("%s 对大家说 %s\n",newnode->name, newnode->msg);
history_recv(newnode, MSG_RECV_ALL);
break;
}
case DIS_NAME:
{
printf("%s\n",newnode->name);
break;
}
case RECV_FILE:
{
printf("%s 向你发送了%s文件\n", newnode->name, newnode->file_name);
recv_file(newnode);
printf("接受成功\n");
break;
}
case PASSWD_SUCCESS:
{
printf("密码修改成功\n");
break;
}
case STOP_SAY_OK:
{
printf("禁言成功\n");
break;
}
case No_say:
{
printf("你已经被禁言\n");
break;
}
case NOT_STOP_SAY:
{
printf("该用户没有被禁言\n");
break;
}
case LET_SAY_OK:
{
printf("解禁成功\n");
break;
}
case Ok_say:
{
printf("你已被解禁\n");
break;
}
case No_online:
{
printf("当前没有其他用户在线\n");
break;
}
case T_OK:
{
printf("踢人成功\n");
break;
}
case YOU_OUT:
{
printf("你已被踢下线\n");
Flag = YOU_OUT;
break;
}
case QUIT_OK:
{
printf("期待你的回归\n");
break;
}
default:
{
printf("read_msg error!\n");
exit(0);
}
}
}
}
Scripts:
CC := gcc
CFLAGS := -Wall -O3
Libs = -lpthread -lsqlite3
Target := client
Source := $(wildcard src/*.c)
Objs := $(patsubst %.c,%.o,$(Source))
Modules += chat get log_reg main menu read_msg send_recv_file sup tcp_socket
AllObjs := $(addsuffix /src/*.o,$(Modules))
/*********************************************************
- File name :send_recv.c
* ******************************************************/
#include "../../include/net.h"
int send_1(int sfd)
{
Node *newnode = (Node *) malloc (sizeof(Node));
memset(newnode, 0, sizeof(Node));
/* 发送文件验证 */
newnode->ack = send_file;
printf("你想对谁发送文件:\n");
scanf("%s",newnode->toname);
/* 异常处理 */
if(getchar() != '\n')
{
printf("用户名格式不正确\n");
printf("\n请重新输入指令\n");
while(getchar() != '\n')
{
continue;
}
return 0;
}
printf("请输入要传输文件的文件名:\n");
scanf("%s", newnode->file_name);
getchar();
int fd = open(newnode->file_name, O_RDONLY);
int file_len = lseek(fd, 0, SEEK_END);
int read_len = 0;
int n = 0;
/* 将文件写入结构体 */
lseek(fd, 0, SEEK_SET);
while(read_len < file_len)
{
n = read(fd, newnode->file_msg + read_len, file_len - read_len);
if(n < 0)
{
perror("write file error!\n");
return 0;
}
read_len += n;
}
/* 发送给服务器 */
write(sfd, newnode, sizeof(Node));
return 0;
}
int recv_file(Node *newnode)
{
int fd;
int recv_len = strlen(newnode->file_msg);
int write_len = 0;
int n = 0;
if((fd = open("abcd", O_RDWR | O_CREAT | O_TRUNC, 0755)) < 0)
{
perror("open error!\n");
exit(0);
}
while(write_len < recv_len)
{
n = write(fd, newnode->file_msg + write_len , recv_len - write_len);
if(n < 0)
{
perror("read file error");
exit(0);
}
write_len += n;
}
return 0;
}
/*********************************************************
- File name :sup.c
* ******************************************************/
#include "../../include/net.h"
int stop_say_1(int sfd)
{
Node *newnode = (Node *) malloc (sizeof(Node));
memset(newnode, 0, sizeof(Node));
newnode->ack = stop_say;
printf("请输入你将谁禁言\n");
scanf("%s",newnode->name);
getchar();
write(sfd, newnode, sizeof(Node));
return 0;
}
int let_say_1(int sfd)
{
Node *newnode = (Node *) malloc (sizeof(Node));
memset(newnode, 0, sizeof(Node));
newnode->ack = let_say;
printf("请输入你要解禁的用户名\n");
scanf("%s",newnode->name);
getchar();
write(sfd, newnode, sizeof(Node));
return 0;
}
int t_man_1(int sfd)
{
Node *newnode = (Node *) malloc (sizeof(Node));
memset(newnode, 0, sizeof(Node));
newnode->ack = t_man;
printf("你想踢谁\n");
scanf("%s",newnode->name);
write(sfd, newnode, sizeof(Node));
getchar();
return 0;
}
/*********************************************************
- File name :tcp_socket.c
* ******************************************************/
#include "../../include/net.h"
int tcp_connect(const char *ip)
{
int sfd;
if((sfd = socket(AF_INET, SOCK_STREAM,0)) == -1)
{
perror("socket error!\n");
exit(-1);
}
struct sockaddr_in severaddr;
bzero(&severaddr,sizeof(severaddr));
severaddr.sin_family = AF_INET;
severaddr.sin_addr.s_addr = inet_addr(ip);
severaddr.sin_port = htons(8888);
if(connect(sfd, (struct sockaddr *)&severaddr, sizeof(severaddr)) == -1)
{
perror("connect error!\n");
close(sfd);
exit(-1);
}
return sfd;
}
- 基于TCP协议简易聊天室(客户端)
- 基于TCP协议简易聊天室(服务器端)
- 基于UDP的简易聊天室(客户端)
- 聊天室 1.0 (TCP协议)客户端
- 基于TCP协议的聊天室
- 基于TCP的简易聊天室系统
- Linux下面基于TCP多线程聊天室(客户端)
- 【Java】基于TCP协议多线程服务器-客户端交互控制台聊天室简例
- [Qt] 基于Tcp协议的聊天室实现
- 基于TCP网络通信的简易多线程GUI聊天室
- C++网络编程基础代码(客户端)--基于TCP协议
- 基于Linux系统的tcp协议的即时通信系统(聊天室)
- JAVA 基于TCP协议编写的Socket聊天室程序
- java编写的基于TCP协议的聊天室
- linux下基于TCP协议的多线程聊天室的搭建
- 聊天室 1.0 (TCP协议)服务器
- 基于TCP/IP协议的客户端应用程序
- 基于TCP协议的服务器/客户端程序
- Ubuntu中文版系统文件夹改成英文方法
- 文件上传-commons-fileupload组件
- Activity通信-传递对象、集合总结
- Matlab读取二进制文件
- Python3之列表(list)
- 基于TCP协议简易聊天室(客户端)
- Linux下Samba服务器配置,已成功
- C#实现的调用Quartz.dll的定时任务插件
- View的事件分发机制
- 数据库设计--库的拆分与表的分割
- 文章标题
- python的一些内建异常
- Hankson趣味题
- 【Java】Java的==和equals()以及自动装箱拆箱