Linux下的shell聊天室:
里程碑0:
1、基于C/S架构的聊天室,分为客户端和服务器。
2、客户端登陆时输入服务器IP、port、 昵称不能重复
里程碑1:
3、可以群发消息或指定接收人
4、admin账号可以踢人
5、新加入用户可以看到聊天历史记录
里程碑2:
5、可以互传文件
6、保存聊天信息
里程碑3:
7、第一次登录时,需要注册。
技术设计:
1、在shell下的图形库:curses
2、多线程:pthread
3、网络:socket
4、消息结构:
<span style="font-size:18px;">struct msg_st
{
char name[256];
char to[256];
char data[4096];
char cmd[256];
};</span>
其中,关于cmd内容:
//login 登陆
//offline 服务器即将踢人
//user 服务发送的用户列表,数据在data里
//chat 表示这是一条消息,数据在data里
5、服务器用了epoll来监听多个fd
登陆界面:
聊天界面:
以下是源代码(里程碑1):
//client.c
#include<unistd.h>
#include<stdio.h>
#include<stdlib.h>
#include<errno.h>
#include<sys/types.h>
#include<sys/socket.h>
#include<netdb.h>
#include<netinet/in.h>
#include<arpa/inet.h>
#include<fcntl.h>
#include<sys/ioctl.h>
#include<sys/select.h>
#include<pthread.h>
#include<ncurses.h>
#include <sys/epoll.h>
#include "shared_vals.h"
#include"chat_net.h"
#include"chat_ui.h"
char promote[256]= {0};
int main(int argc, char * argv[])
{
ui_init();
do
{
ui_login(ip,&port,name);
if(0==net_login(ip,&port,name))
{
ui_alert("Login ok!");
break;
}
else
{
ui_alert("Login failed!");
}
}
while(1);
ui_init_wins();
ui_refresh_wins();
wprintw(win[1],"IP:%s\nPORT:%d\nNAME:%s",ip,port,name);
ui_refresh_wins();
// int i=0;
// for(i=0; i<100; i++)
// ui_print_msg("This is a test message!");
//generate promote as [from] [to]
sprintf(promote,"[%s]:", name);
//start recev process
pthread_t thread;
int res=pthread_create(&thread,NULL,(void *)net_getmsg,(void*)NULL);
if(res!=0)
{
ui_alert("Error");
getch();
}
while(1)
{
ui_promote(promote);
int c=0;
struct msg_st msg_client;
memset((void *)&msg_client,0,sizeof(msg_client));
ui_getmsg(msg_client.data);
strcpy(msg_client.name,name);
strcpy(msg_client.cmd,"chat");
write(sockfd,&msg_client,sizeof(msg_client));
}
net_end();
ui_end();
exit(0);
}
//chat_net.h
#ifndef _CHAT_NET_H_
#define _CHAT_NET_H_
#include<unistd.h>
#include<stdio.h>
#include<stdlib.h>
#include<errno.h>
#include<sys/types.h>
#include<sys/socket.h>
#include<netdb.h>
#i