linux下用线程实现的聊天室 服务器部分
来源:互联网 发布:中山陵哭陵事件 知乎 编辑:程序博客网 时间:2024/06/05 10:53
#include <stdlib.h>
#include <stdio.h>
#include <errno.h>
#include <string.h>
#include <netdb.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <sys/socket.h>
#include <sys/stat.h>
#include <unistd.h>
#include <arpa/inet.h>
#include <ctype.h>
#include <sqlite3.h>
#include <fcntl.h>
#include <time.h>
#include <pthread.h>
#define PORT 9071//定义的端口号为 9071
#define BUFF_MAX 1024//缓冲器的最大长度
#define MSG_MAX 924//msg的最大长度
#define LISENT_BACK 10
/*<普通用户>*/
#define HELP 1 //帮助信息显示
#define LOG 2 //登录
#define REG 3 //注册
#define PTO 4 //悄悄话
#define CTO 5 //群发消息
#define VIM 6 //查看在线用户
#define VOM 7 //查看所有用户
#define CAT 8 //查看聊天历史记录
#define FAC 9 //特殊表情
#define ESC 10 //退出
/*<超级管理员>*/
#define KIC 11 // 踢人
#define SCL 12 //禁言
#define RCL 13 //撤销禁言
int servsock_fd;//定义一个全局变量来保存客户端sock地址
struct man //用于注册信息的结构体
{
char name[20];
char passward[20];
};
struct sockfd_lis//用于存放新创建fd,和登录的用户名
{
pthread_t sock_fd;
char name[20];
char msg[MSG_MAX];
struct sockfd_lis *next;
};
struct msg_chat//用于存放客户端发送的动作
{
int action[1];
char name[20];
};
int flag = 0;
typedef struct sockfd_lis * line;
line head;
/*********************************************************************************************************************/
void friend_num(int x,char num[])//将整型转换为字符型
{
printf("..friend_num1\n");
int i = 0;
int j = x;
while(j != 0)
{
j = j/10;
i++;
}
while(i+1!= 0)
{
num[(i--)-1] = x%10 + '0';
x = x/10;
}
printf("..friend_num0\n");
return;
}
/*********************************************************************************************************************/
/*链表部分的程序*/
/*创建链表,用于存放新创建线程,和登录的用户名*/
line creat_lin(line *head)
{
printf("..creat_lin1\n");
*head = NULL;
printf("..creat_lin0\n");
return *head;
}
/*尾部插入链表*/
int end_insert(line *head,line *newnode)
{
printf("..end_insert1\n");
if(*newnode == NULL)
{
printf("..end_insert0\n");
return 0;
}
if(*head == NULL)
{
(*newnode)->next = NULL;
*head = *newnode;
printf("..end_insert0\n");
return 1;
}
line temp = *head;
while(temp->next != NULL)
{
temp = temp->next;
}
temp->next = *newnode;
(*newnode)->next = NULL;
printf("..end_insert0\n");
return 1;
}
/*查找指定在线用户sock_fd*/
int find_lin(line *head,char* name)
{
printf("..find_lin1\n");
line temp = *head;
while(temp != NULL)
{
if(0 == strcmp(temp->name,name))
{
printf("pthread id is %d", temp->sock_fd);
printf("..find_lin0\n");
return temp->sock_fd;
}
temp = temp->next;
}
printf("..find_lin0\n");
return 0;
}
/*指定在线用户存储信息*/
void find_lin_msg(line *head,pthread_t sock_fd,char msg[])
{
printf("..find_lin_msg1\n");
line temp = *head;
while(temp != NULL)
{
if(pthread_equal(sock_fd,temp->sock_fd))
{
strcpy(temp->msg,msg);
}
temp = temp->next;
}
printf("..find_lin_msg0\n");
return;
}
/*用户下线,删除该用户所在结点*/
int delete_lin(line *head,char* name)
{
printf("..delete_lin1\n");
if(*head == NULL)
{
printf("..delete_lin0\n");
return 0;
}
line temp = *head;
if(0 == strcmp((*head)->name,name))//删除点在头部
{
line temp = *head;
*head = (*head)->next;
free(temp);
temp = NULL;
printf("..delete_lin0 head\n");
return 1;
}
line ptr = temp;
temp = temp->next;
while(temp!= NULL)//删除点在中间
{
if(0 == strcmp(temp->name,name))
{
ptr->next = temp->next;
free(temp);
temp = NULL;
printf("..delete_lin0 middle\n");
return 1;
}
ptr = temp;
temp = temp->next;
}
printf("..delete_lin0\n");
return 0;
}
/*输出链表*/
void display_lin(line * head)
{
printf("..display_lin1\n");
line temp = * head;
while(temp != NULL)
{
printf("%s\n",temp->name);
temp = temp ->next;
}
printf("..display_lin0\n");
return;
}
/*显示在线用户*/
void display_lin_vim(line * head,char buffer[])
{
printf("..display_lin_vim1\n");
line temp = * head;
bzero(buffer, sizeof(buffer)); /* 清空缓冲区 */
strcpy(buffer,"当前在线用户有:\n");
while(temp != NULL)
{
strcat(buffer,temp->name);
strcat(buffer,"\n");
temp = temp ->next;
}
printf("..display_lin_vim0\n");
return;
}
/*获取cto_fd*/
void display_lin_cto(line * head,char buffer[])
{
printf("..display_lin_cto1\n");
ssize_t write_fd;//存放读和写的描述符
line temp = * head;
while(temp != NULL)
{
write_fd = write(temp->sock_fd,buffer,BUFF_MAX);
if(-1 == write_fd)
{
perror("write");
exit(EXIT_FAILURE);
}
temp = temp ->next;
}
printf("..display_lin_cto0\n");
return;
}
/**************************************************************************************************************/
/*************************************************************************************************************/
/////////////////////////////////////////////////////<chat_log登录>////////////////////////////////////////////////////////
void chat_log(int sock_fd,struct man *id)
{
printf("log!\n");
printf("state-> %d: ",LOG);
sqlite3*db = NULL;//定义一个数据库文件
char **result = NULL;//定义一个存放字符串的数组保存查询结果
char *errmsg = NULL;//定义保存错误信息
int rc;//数据库函数的返回值
int row;//需要查找的行
int column;//需要查找的列
char sql[BUFF_MAX];//数据库操作的字符串
char buffer[BUFF_MAX] ={0};//缓冲区
line newnode;//该指针用于添加新用户于链表
line temp;//用于遍历链表
ssize_t write_fd,read_fd;//读和写的描述符
/*开始登录*/
/*读用户信息*/
printf("读用户名\n");
read_fd = read(sock_fd, (*id).name, (size_t)BUFF_MAX);//读用户名
if(-1 == read_fd)
{
perror("read");
exit(EXIT_FAILURE);
}
printf("name is %s\n",(*id).name);
printf("读密码\n");
read_fd = read(sock_fd,(*id).passward, (size_t)BUFF_MAX);//读密码
if(-1 == read_fd)
{
perror("read");
exit(EXIT_FAILURE);
}
printf("passward input down\n");
/*服务器反应部分*/
char *a[1] = {0};
rc = sqlite3_open("serve_data.db", &db);
printf("查询数据库中的该用户\n");
sprintf(sql, "select * from user_table where name='%s'", (*id).name);//查询数据库中的该用户
rc = sqlite3_get_table(db, sql, &result, &row, &column, &errmsg);
//<o用户o>//
if (0 != strcmp(result[0],"name")) /* 检查是否在数据库中找到该用户 */
{
strcpy(buffer, "用户未注册请先注册\n");
printf("%s",buffer);
write_fd = write(sock_fd, buffer,sizeof(buffer));
if(-1 == write_fd)
{
perror("write");
exit(EXIT_FAILURE);
}
memset(buffer,0,sizeof(buffer));//清空缓存中的内容
sqlite3_free_table(result);
sqlite3_close(db);
printf("log out!\n");
return;
}
if (strcmp((*id).passward, result[3]) != 0)/*检查用户密码是否输入正确*/
{
bzero(buffer, sizeof(buffer)); //清空缓冲区
strcpy(buffer, "密码错误");
write_fd = write(sock_fd, buffer,sizeof(buffer));
if(-1 == write_fd)
{
perror("write");
exit(EXIT_FAILURE);
}
memset(buffer,0,sizeof(buffer));//清空缓存中的内容
sqlite3_free_table(result);
sqlite3_close(db);
printf("log out!\n");
return;
}
else
{
/* 检查是否已经登录*/
if(find_lin(&head,(*id).name))
{
// memset(buffer, 0, BUFF_MAX);//初始化
bzero(buffer, sizeof(buffer)); //清空缓冲区
strcpy(buffer, "你的帐号已登录,不能重复登录\n");
printf("%s",buffer);
write_fd = write(sock_fd, buffer,sizeof(buffer));
if(-1 == write_fd)
{
perror("write");
exit(EXIT_FAILURE);
}
memset(buffer,0,sizeof(buffer));//清空缓存中的内容
sqlite3_free_table(result);
sqlite3_close(db);
printf("log out!\n");
return;
}
}
/*登录成功*/
printf("%s\n",(*id).name);
//memset(buffer, 0, BUFF_MAX);//初始化
bzero(buffer, sizeof(buffer)); //清空缓冲区
if(0 == strcmp((*id).name,"admin"))
{
strcpy(buffer, "超级管理员成功登录\n");
}
if(0 != strcmp((*id).name,"admin"))
{
strcpy(buffer, "登录成功\n");
}
printf("%s",buffer);
write_fd = write(sock_fd, buffer,sizeof(buffer));
if(-1 == write_fd)
{
perror("write");
exit(EXIT_FAILURE);
}
int ter = open("serve_log.txt", O_RDWR|O_CREAT|O_APPEND, S_IRUSR);
if(-1 == ter)
{
perror("open");
exit(EXIT_FAILURE);
}
strcpy(buffer, (*id).name);
strcat(buffer, "于");
time_t t;
time(&t);
strcat(buffer, ctime(&t));
strcat(buffer, " 成功登录\n");
write(ter,buffer,(size_t)(strlen(buffer)));
if( -1 == ter)
{
perror("write");
exit(EXIT_FAILURE);
}
bzero(buffer, sizeof(buffer)); //清空缓冲区
/*将成功登录的用户加入链表*/
if((newnode = (line)malloc (sizeof(struct sockfd_lis))) == 0)//给新结点分配空间
{
printf("malloc error!\n");
exit(EXIT_FAILURE);
}
if(end_insert(&head,&newnode) == 0)//在链表中添加新结点
{
printf("insert error");
exit(EXIT_FAILURE);
}
strcpy(newnode-> name, (*id).name);//登录的用户名
newnode-> sock_fd = sock_fd;//客户端
printf("显示当前在现用户\n");
display_lin(&head);
memset((struct sockaddr_in*)&buffer, 0, sizeof(buffer));//清空缓存
sqlite3_free_table(result);
sqlite3_close(db);
printf("log out!\n");
return;
}
/////////////////////////////////////////////////<chat_log登录>//////////////////////////////////////////////////////////
//////////////////////////////////////////////////<chat_reg注册>////////////////////////////////////////////////////////
void chat_reg(int sock_fd,struct man *id)
{
printf("reg!\n");
printf("state ->%d: ",REG);
static sqlite3 *db = NULL;//定义一个数据库文件
static char *errmsg = NULL;//定义用来保存错误的信息
int rc;//数据库函数返回值
char sql[BUFF_MAX];//数据库操作字符串
char buffer[BUFF_MAX] ={0};//定义缓冲区
ssize_t write_fd,read_fd;//写的描述符
/*开始注册*/
/*读用户信息*/
read_fd = read(sock_fd, (*id).name, (size_t)BUFF_MAX);//读用户名
if(-1 == read_fd)
{
perror("read");
exit(EXIT_FAILURE);
}
printf("name is %s\n", (*id).name);
read_fd = read(sock_fd,(*id).passward, (size_t)BUFF_MAX);//读密码
if(-1 == read_fd)
{
perror("read");
exit(EXIT_FAILURE);
}
printf("passward input down\n");
/*在数据库之中插入新用户和密码*/
rc = sqlite3_open("serve_data.db",&db);//创建一个名为sreve_data.db的数据库文件
if (rc)
{
strcpy(buffer, "error in creat serve_data.db!\n");
printf("reg out!\n");
return;
}
//sprintf(sql,"create table user_table(name text, password text,primary key(name))");//给sql语句赋值创建表类型
/*rc = sqlite3_exec(db,sql,0,0,&errmsg);//数据库创建表
if (rc)
{
strcpy(buffer, "error in creat user_table!\n");
printf("reg out!\n");
return;
} */
sprintf(sql,"insert into user_table values('%s','%s')",(*id).name,(*id).passward);
printf("%s insert ",(*id).name);
rc = sqlite3_exec(db,sql,0,0,&errmsg);//插入数据
if (rc)//如果用户已存在
{
printf("error!\n");
memset(buffer, 0, BUFF_MAX);//初始化
strcpy(buffer, "该用户已经存在,请您更换其他的用户名!\n");
write_fd = write(sock_fd, buffer,sizeof(buffer));
if(-1 == write_fd)
{
perror("write");
exit(EXIT_FAILURE);
}
}
else//注册成功
{
printf("%s reg successful!\n",(*id).name);
memset(buffer, 0, BUFF_MAX);//初始化
strcpy(buffer,"注册成功,请您登录!\n");
write_fd = write(sock_fd, buffer,sizeof(buffer));
if(-1 == write_fd)
{
perror("write");
exit(EXIT_FAILURE);
}
}
sqlite3_close(db);
printf("reg out!\n");
return;
}
//////////////////////////////////////////////////<chat_reg注册>//////////////////////////////////////////////////////////////
//////////////////////////////////////////////////<chat_pto私聊>////////////////////////////////////////////////////////////////
void chat_pto(int sock_fd,struct man *id)
{
printf("pto!\n");
printf("state ->%d: ",PTO);
ssize_t read_fd, write_fd;//存放读和写的描述符
struct msg_chat action;//用来存放动作
char pto_name[20];//用于存放接收消息的用户
char buffer[BUFF_MAX] = {0};//用于存放接收的信息
char msg[MSG_MAX] = {0};//用于存放信息
pthread_t pto_fd;//用于存放接收用户的套接口描述符
action.action[0] = PTO;
int onlin[1] = {0};
/*开始私聊*/
printf("%s to ",(*id).name);
read_fd = read(sock_fd,pto_name,20);//读取客户端发来的用户名
if (-1 == read_fd)
{
perror("write");
exit(EXIT_FAILURE);
}
printf("%s\n",pto_name);
pto_fd = find_lin(&head,pto_name);//获取该用户线程的描述符
if(0 == pto_fd)//不在线
{
bzero(buffer, sizeof(buffer)); /* 清空缓冲区 */
strcpy(buffer,"该用户不在线,不能发送消息\n");
printf("%s\n",buffer);
write_fd = write(sock_fd,buffer,sizeof(buffer));
if(-1 == write_fd)
{
perror("write");
exit(EXIT_FAILURE);
}
memset(buffer,0,sizeof(buffer));//清空缓存中的内容
printf("pto out!\n");
return;
}
if(pto_fd)
{
read_fd = read(sock_fd,msg,MSG_MAX);//接收用户端发来的消息
if(-1 == read_fd)
{
perror("read");
exit(EXIT_FAILURE);
}
printf("%s\n",buffer);
bzero(buffer, sizeof(buffer)); /* 清空缓冲区 */
strcpy(buffer,"\nrecive a massage!");
time_t t;
time(&t);
strcat(buffer, ctime(&t));
//strcat(buffer,"\n");
strcat(buffer,(*id).name);
strcat(buffer, "悄悄说->:");
strcat(buffer,msg);
strcat(buffer,"\n");
printf("%s",buffer);
write_fd = write(pto_fd,buffer,sizeof(buffer));
if(-1 == write_fd)
{
perror("write");
exit(EXIT_FAILURE);
}
int ter = open("chat.txt", O_RDWR|O_CREAT|O_APPEND, S_IRUSR);
if(-1 == ter)
{
perror("open");
exit(EXIT_FAILURE);
}
write(ter,buffer,(size_t)(strlen(buffer)));
if( -1 == ter)
{
perror("write");
exit(EXIT_FAILURE);
}
memset(buffer,0,sizeof(buffer));//清空缓存中的内容
}
printf("pto out!\n");
return;
}
//////////////////////////////////////////////////<chat_pto私聊>////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////<chat_cto公聊>////////////////////////////////////////////////////////////////
void chat_cto(int sock_fd,struct man *id)
{
printf("cto!\n");
printf("state ->%d: ",CTO);
ssize_t read_fd, write_fd;//存放读和写的描述符
struct msg_chat action;//用来存放动作
char buffer[BUFF_MAX] = {0};//用于存放接收的信息
char msg[MSG_MAX] = {0};//用于存放信息
action.action[0] = CTO;
int onlin[1] = {0};
/*开始公聊*/
printf("%s ",(*id).name);
bzero(buffer, sizeof(buffer)); /* 清空缓冲区 */
read_fd = read(sock_fd,msg,MSG_MAX);//接收用户端发来的消息
if(-1 == read_fd)
{
perror("read");
exit(EXIT_FAILURE);
}
printf("%s\n",buffer);
strcpy(buffer,"recive a massage!");
time_t t;
time(&t);
strcat(buffer, ctime(&t));
//strcat(buffer,"\n");
strcat(buffer,(*id).name);
strcat(buffer, "对大家说->:");
strcat(buffer,msg);
strcat(buffer,"\n");
printf("%s",buffer);
//display_lin_cto(&head,buffer);
////////////////////////////
line temp = head;
while(temp != NULL)
{
write_fd = write(temp->sock_fd,buffer,sizeof(buffer));
if(-1 == write_fd)
{
perror("write");
exit(EXIT_FAILURE);
}
temp = temp ->next;
}
////////////////////////////
int ter = open("chat.txt", O_RDWR|O_CREAT|O_APPEND, S_IRUSR);
if(-1 == ter)
{
perror("open");
exit(EXIT_FAILURE);
}
write(ter,buffer,(size_t)(strlen(buffer)));
if( -1 == ter)
{
perror("write");
exit(EXIT_FAILURE);
}
memset(buffer,0,sizeof(buffer));//清空缓存中的内容
printf("cto out!\n");
return;
}
//////////////////////////////////////////////////<chat_cto公聊>////////////////////////////////////////////////////////////////
/////////////////////////////////////////////<chat_vim显示在线用户>///////////////////////////////////////////////////////
void chat_vim(int sock_fd,struct man * id)
{
printf("vim!\n");
printf("state ->%d: ",VIM);
char buffer[BUFF_MAX] = {0};//用于存放接收的信息
ssize_t read_fd, write_fd;//存放读和写的描述符
bzero(buffer, sizeof(buffer)); /* 清空缓冲区 */
display_lin_vim(&head,buffer);
write_fd = write(sock_fd,buffer,sizeof(buffer));
if(-1 == write_fd)
{
perror("write");
exit(EXIT_FAILURE);
}
memset(buffer,0,sizeof(buffer));//清空缓存中的内容
printf("vim out!\n");
return;
}
//////////////////////////////////////////////<chat_vim显示在线用户>//////////////////////////////////////////////////////
//////////////////////////////////////////////<chat_vom显示所有用户>/////////////////////////////////////////////////////
void chat_vom(int sock_fd,struct man * id)
{
printf("vom!\n");
printf("state ->%d: ",VOM);
sqlite3*db = NULL;//定义一个数据库文件
char **result = NULL;//定义一个存放字符串的数组保存查询结果
char *errmsg = NULL;//定义保存错误信息
int rc;//数据库函数的返回值
int row;//需要查找的行
int column;//需要查找的列
char sql[BUFF_MAX];//数据库操作的字符串
char num[1024] = {0};
int i = 1;
char buffer[BUFF_MAX] = {0};//用于存放接收的信息
ssize_t read_fd, write_fd;//存放读和写的描述符
bzero(buffer, sizeof(buffer)); /* 清空缓冲区 */
rc = sqlite3_open("serve_data.db", &db);
sprintf(sql, "select * from user_table");//查询数据库中的该用户
rc = sqlite3_get_table(db, sql, &result, &row, &column, &errmsg);
friend_num(row,num);
strcpy(buffer,"您共有好友数为");
strcat(buffer,num);
strcat(buffer,"\n");
for(i = 2;i < row * column+2;i = i+2)
{
printf("%s\n",result[i]);
strcat(buffer,result[i]);
strcat(buffer,"\n");
}
write_fd = write(sock_fd,buffer,sizeof(buffer));
if(-1 == write_fd)
{
perror("write");
exit(EXIT_FAILURE);
}
memset(buffer,0,sizeof(buffer));//清空缓存中的内容
printf("vom out!\n");
return;
}
//////////////////////////////////////////////<chat_vom显示所有用户>/////////////////////////////////////////////////////
///////////////////////////////////////////////////<chat_kic踢人>////////////////////////////////////////////////////////////////
void chat_kic(int sock_fd,struct man * id)
{
printf("kic!\n");
printf("state ->%d: ",KIC);
ssize_t read_fd, write_fd;//存放读和写的描述符
char kic_name[20] = {0};
int kic_fd;
char buffer[BUFF_MAX] = {0};//用于存放发送的信息
read_fd = read(sock_fd,kic_name, 20);//所踢人的姓名
if (-1 == read_fd)
{
perror("read");
exit(EXIT_FAILURE);
}
bzero(buffer, sizeof(buffer)); /* 清空缓冲区 */
strcpy(buffer,"该人已经被踢下线\n");
write_fd = write(sock_fd,buffer,BUFF_MAX);//
if (-1 == write_fd)
{
perror("write");
exit(EXIT_FAILURE);
}
bzero(buffer, sizeof(buffer)); /* 清空缓冲区 */
kic_fd = find_lin(&head,kic_name);
strcpy(buffer,"你已经被踢下线\n");
write_fd = write(kic_fd,buffer,BUFF_MAX);//
if (-1 == write_fd)
{
perror("write");
exit(EXIT_FAILURE);
}
delete_lin(&head,kic_name);
memset(kic_name,0,sizeof(kic_name));//清空缓存中的内容
printf("显示当前在现用户\n");
display_lin(&head);
printf("kic out!\n");
return;
}
///////////////////////////////////////////////////<chat_kic踢人>////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////<chat_scl禁言>////////////////////////////////////////////////////////////////
void chat_scl(int sock_fd,struct man * id)
{
printf("scl!\n");
printf("state ->%d: ",SCL);
ssize_t read_fd, write_fd;//存放读和写的描述符
char scl_name[20] = {0};
int scl_fd;
char buffer[BUFF_MAX] = {0};//用于存放发送的信息
read_fd = read(sock_fd,scl_name, 20);//所禁言人的姓名
if (-1 == read_fd)
{
perror("read");
exit(EXIT_FAILURE);
}
bzero(buffer, sizeof(buffer)); /* 清空缓冲区 */
strcpy(buffer,"该人已经被禁言\n");
write_fd = write(sock_fd,buffer,BUFF_MAX);
if (-1 == write_fd)
{
perror("write");
exit(EXIT_FAILURE);
}
bzero(buffer, sizeof(buffer)); /* 清空缓冲区 */
scl_fd = find_lin(&head,scl_name);
strcpy(buffer,"你已经被禁言\n");
write_fd = write(scl_fd,buffer,BUFF_MAX);
if (-1 == write_fd)
{
perror("write");
exit(EXIT_FAILURE);
}
printf("scl out!\n");
return;
}
///////////////////////////////////////////////////<chat_scl禁言>////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////<chat_rcl撤消禁言>//////////////////////////////////////////////////////////
void chat_rcl(int sock_fd,struct man * id)
{
printf("rcl!\n");
printf("state ->%d: ",RCL);
ssize_t read_fd, write_fd;//存放读和写的描述符
char rcl_name[20] = {0};
int rcl_fd;
char buffer[BUFF_MAX] = {0};//用于存放发送的信息
read_fd = read(sock_fd,rcl_name, 20);//所禁言人的姓名
if (-1 == read_fd)
{
perror("read");
exit(EXIT_FAILURE);
}
bzero(buffer, sizeof(buffer)); /* 清空缓冲区 */
strcpy(buffer,"该人已经解禁\n");
write_fd = write(sock_fd,buffer,BUFF_MAX);
if (-1 == write_fd)
{
perror("write");
exit(EXIT_FAILURE);
}
bzero(buffer, sizeof(buffer)); /* 清空缓冲区 */
rcl_fd = find_lin(&head,rcl_name);
strcpy(buffer,"你已经被解禁\n");
write_fd = write(rcl_fd,buffer,BUFF_MAX);
if (-1 == write_fd)
{
perror("write");
exit(EXIT_FAILURE);
}
printf("rcl!\n");
return;
}
///////////////////////////////////////////////////<chat_rcl撤消禁言>//////////////////////////////////////////////////////////
///////////////////////////////////////////////////<chat_esc退出>//////////////////////////////////////////////////////////////
void chat_esc(int sock_fd,struct man * id)
{
printf("esc!\n");
printf("state ->%d: ",ESC);
printf("%s\n",(*id).name);
struct sockfd_lis id_lin;
printf("stacte %d : %s \n", ESC,(*id).name);//显示用户名
printf("显示当前在现用户\n");
delete_lin(&head,(*id).name);
display_lin(&head);
(*id).name[0] = '\0';//初始化该用户
printf("esc out!\n");
return;
}
///////////////////////////////////////////////////<chat_esc退出>//////////////////////////////////////////////////////////////
//////////////////////////////////////////////<o处理客户端信息的线程o>////////////////////////////////////////////////////
/*函数主线程部分*/
//主要进行接收客户端发过来的动作,并对动作进行相应的处理
void * serve_request(void* arg)
{
printf("ask_serve\n");
int sock_fd = (int)arg;//获得客户机的端口号
ssize_t read_fd, write_fd;//读和写的描述符
struct man id;//创建一个结构体用于存放客户端的客户信息
memset((struct sockaddr_in*)&id, 0, sizeof(struct man));//初始化
int action[1];//用于存放客户端发来的动作
action[0] = 0;//初始化动作
pthread_t msg_id;//接收服务器线程的id
int ret;
printf("serve request cline_id is %d\n", sock_fd);
while(1)
{
printf("start action is %d.\n",action[0]);
printf("start to read!\n");
/////////////////////////////////////////
read_fd = read(sock_fd, &action[0],1);
if(-1 == read_fd)
{
perror("read");
break;
}
printf("read_fd is %d\n",read_fd);
printf("action is %d.\n",action[0]);
if(0 == action[0])
{ action[0] =1;
printf("please wait...\n");
}
printf("end action is %d.\n",action[0]);
sleep(1);
/*对相应的动作作判断*/
if((LOG == action[0]))
{
printf("chat_log in\n");
chat_log(sock_fd,&id);//登录部分
action[0] = 1;//初始化动作
printf("chat_log out\n");
continue;
}
if(REG == action[0])
{
printf("chat_reg in\n");
chat_reg(sock_fd,&id);//注册部分
action[0] = 1; //初始化动作
printf("chat_reg out\n");
continue;
}
if((PTO == action[0]))
{
printf("chat_pto in\n");
chat_pto(sock_fd,&id);//悄悄话部分
action[0] = 1;//初始化动作
printf("chat_pto out\n");
continue;
}
if((CTO == action[0]))
{
printf("chat_cto in\n");
chat_cto(sock_fd,&id);//公聊部分
action[0] = 1;//初始化动作
printf("chat_cto out\n");
continue;
}
if((VIM == action[0]))
{
printf("chat_vim in\n");
chat_vim(sock_fd,&id);//查看在线状态部分
action[0] = 1;//初始化动作
printf("chat_vim out\n");
continue;
}
if((VOM == action[0]))
{
printf("chat_vom in\n");
chat_vom(sock_fd,&id);//查看所有用户部分
action[0] = 1;//初始化动作
printf("chat_vom out\n");
continue;
}
if((KIC == action[0]))
{
printf("chat_klc in\n");
chat_kic(sock_fd,&id);//踢人部分
action[0] = 1;//初始化动作
printf("chat_kic out\n");
continue;
}
if((SCL == action[0]))
{
printf("chat_scl in\n");
chat_scl(sock_fd,&id);//禁言部分
action[0] = 1;//初始化动作
printf("chat_scl out\n");
continue;
}
if((RCL == action[0]))
{
printf("chat_rcl in\n");
chat_rcl(sock_fd,&id);//撤消禁言部分
action[0] = 1;//初始化动作
printf("chat_rcl out\n");
continue;
}
if((ESC == action[0]))
{
printf("chat_esc in\n");
chat_esc(sock_fd,&id);//登录部分
action[0] = 1;//初始化动作
printf("chat_esc out\n");
continue;
}
if(0 == action[0])
{
printf("please wait...");
}
printf("this is error0\n");
break;
}
printf("this is error1\n");
return;
}
//////////////////////////////////////////////<o处理客户端信息的线程o>////////////////////////////////////////////////////
////////////////////////////////////////////////////////////<main>//////////////////////////////////////////////////////////////////
int main()
{
int cilnsock_fd;//保存客户端sock地址
int ret;//用于检测绑定.侦听.关闭的返回值
struct sockaddr_in servaddr,clinaddr;//服务器和客户端地址的结构体
socklen_t cli_addr_len;//用于存放地址结构体的长度
/*创建一个套接口*/
servsock_fd = socket(AF_INET,SOCK_STREAM, 0);
if(-1 == servsock_fd)
{
perror("socket");
exit(EXIT_FAILURE);
}
/*初始化客户端地址*/
memset((struct sockaddr_in*)&servaddr, 0, sizeof(struct sockaddr_in));
servaddr.sin_family = AF_INET;//ipv4
servaddr.sin_addr.s_addr = htonl(INADDR_ANY);//服务器地址
servaddr.sin_port = htons(PORT);//主机接口
int opt = 1;
setsockopt(servsock_fd,SOL_SOCKET,SO_REUSEADDR,&opt,sizeof(opt));
/*绑定服务器地址与套接口*/
ret = bind(servsock_fd, (struct sockaddr *) &servaddr, (socklen_t)sizeof(servaddr));
if(-1 == ret)
{
perror("bind");
exit(EXIT_FAILURE);
}
/*监听*/
ret = listen(servsock_fd,LISENT_BACK);
if(-1 == ret)
{
perror("listen");
exit(EXIT_FAILURE);
}
//creat_lin(&head);//创建线程链表头部
while(1)
{
cli_addr_len = sizeof(clinaddr);//用于存放地址结构体的长度
printf("Waiting for client...\n");
cilnsock_fd = accept(servsock_fd, (struct sockaddr *)&clinaddr, &cli_addr_len );//接收
if(-1 == cilnsock_fd)
{
perror("accept");
exit(EXIT_FAILURE);
}
printf("state-> 0: Connection from IP %s\n", inet_ntoa(clinaddr.sin_addr));
int err;//保存线程的返回值
pthread_t tid;//保存线程的id
tid = pthread_create(&tid, NULL, serve_request,(void *)cilnsock_fd);//创建一个新的线程分配给新登录的客户端
if (0 != tid)
{
printf("Create thread fail:%s\n", strerror(err));
exit(EXIT_FAILURE);
}
}
exit(EXIT_SUCCESS);
}
/////////////////////////////////////////////////////<main>/////////////////////////////////////////////////////////////////////
- linux下用线程实现的聊天室 服务器部分
- linux下用线程实现的聊天室 客户端部分
- linux下用线程实现的聊天室 设计申明书
- 基于Linux c 用socket和线程 实现的简易聊天室之服务器
- Linux下实现聊天室
- Linux下C实现的聊天室
- Linux下C实现的聊天室
- Linux下C实现的聊天室
- linux下 UDP 实现聊天室
- linux系统下实现聊天室
- 基于Linux C 用socket和线程 实现的简易聊天室之客户端
- 实现聊天室的思路 和部分代码
- 聊天室的功能实现(主要部分)
- Linux下利用命名管道实现简单的聊天室
- linux下使用UDP实现简易的多人聊天室
- 利用多线程实现linux下C语言的聊天室程序:
- java 实现单线程的聊天室
- SOCKET网络编程:Linux下实现聊天室
- hdu(1501) Zipper
- [转]C语言获取系统时间的几种方式
- 架构师给程序员的一封信
- _stdcall和__cdecl关键字
- android 使用getIdentifier()获取资源Id
- linux下用线程实现的聊天室 服务器部分
- Linux中的工作队列
- Android Timer使用
- Hdu 1081 To The Max -- DP
- 三十之惑–面霸的八月(第一部分)
- codility上的问题(27) Helium 2013
- linux下用线程实现的聊天室 设计申明书
- 学习boost::program_option
- 明晰C++内存分配的五种方法的区别