基于Linux的多功能聊天室
作者:网络转载 发布时间:[ 2015/2/4 17:58:55 ] 推荐标签:Linux 操作系统
if(tempfd==ONLINEOUT)
{
return ONLINEOUT;
}
else
{
temp->sockfd=tempfd;
return BOOTOK;
}
break;
}
case STEP:
{
int tempfd;
tempfd=read_online_fd(db,errmsg,temp->toname);
if(tempfd==ONLINEOUT)
{
return ONLINEOUT;
}
else
{
flag=update_flag(db,errmsg,temp->toname,0);
if(flag==1)
{
temp->sockfd=tempfd;
}
return flag;
}
break;
}
case BAN:
{
int tempfd;
tempfd=read_online_fd(db,errmsg,temp->toname);
if(tempfd==ONLINEOUT)
{
return ONLINEOUT;
}
else
{
sayflag=read_online_flag(db,errmsg,temp->toname);
if(sayflag==1)
{
return TOFLAGOK;
}
else
{
flag=update_flag(db,errmsg,temp->toname,1);
if(flag==1)
{
temp->sockfd=tempfd;
}
return flag;
}
}
break;
}
case SET:
{
int tempfd;
tempfd=read_online_fd(db,errmsg,temp->toname);
if(tempfd==ONLINEOUT)
{
flag=delete_user(db,errmsg,temp->toname);
return flag;
}
else
{
return ONLINEIN;
}
break;
}
case SEE:
{
return SEEOK;
break;
}
case DATA:
{
return DATAOK;
break;
}
case SEND:
{
int tempfd;
tempfd=read_online_fd(db,errmsg,temp->toname);
if(tempfd==ONLINEOUT)
{
return ONLINEOUT;
}
else
{
temp->sockfd=tempfd;
return SENDOK;
}
break;
}
case CHANGE:
{
flag=read_user(db,errmsg,temp->toname);
if(flag==USERIN)
{
return REGNO;//注册重名
}
else
{
flag=update_user(db,errmsg,temp->name,temp->toname);//????
if(flag==1)
{
sayflag=update_db_data(db,errmsg,temp->name,temp->toname);//修改密码
return sayflag;
}
else
{
return 0;
}
}
break;
}
}
}
那么它的头文件是估计也是用于申明函数的!
int cmd_user(sqlite3*db,char**errmsg,vpChat temp,int sockfd);
socket.c文件分析
#include"data.h"
void mybzero(struct sockaddr_in*sin)//对server_addr_in结构进行赋值
{
bzero(sin,sizeof(struct sockaddr_in));/*先清零*/
sin->sin_family=AF_INET;//
sin->sin_addr.s_addr=htonl(INADDR_ANY);//表示接受任何ip地址将ip地址转换成网络字节序
sin->sin_port=htons(portnumber);//将端口号转换成网络字节序
}
int mysocket()//调用socket函数创建一个TCP协议套接口
{
int lfd;
if((lfd=socket(AF_INET,SOCK_STREAM,0))==-1)//AF_INET:IPV4;SOCK_STREAM:TCP
{
fprintf(stderr,"Socket error:%s a",strerror(errno));
exit(1);
}
return lfd;
}
void mybind(int lfd,struct sockaddr_in*sin) //调用bind函数将serer_addr结构绑定到sockfd上
{
if(bind(lfd,(struct sockaddr*)(sin),sizeof(struct sockaddr))==-1)
{
fprintf(stderr,"Bind error:%s a",strerror(errno));
exit(1);
}
}
void mylisten(int lfd)//开始监听端口等待客户的请求
{
if(listen(lfd,20)==-1)
{
fprintf(stderr,"Listen error:%s a",strerror(errno));
exit(1);
}
}
int myaccept(int lfd,struct sockaddr_in*cin,socklen_t*addr_len)//接受客户端的请求
{
int cfd;
if((cfd=accept(lfd,(struct sockaddr*)cin,addr_len))==-1)
{
fprintf(stderr,"Accept error:%s a",strerror(errno));
exit(1);
}
return cfd;
}
void mywrite(vpChat temp)
{
int num;
if((num=write(temp->sockfd,temp,sizeof(stChat)))==-1)
{
printf("send error! ");
}
}
服务器主程序
朱程序里面主要是打开数据库,初始化数据库,及用于显示数据库的命令,下面为代码部分
#include"data.h"
#include"package.h"
void display(stChat temp)//用于显示发送命令
{
printf("name=%s ",temp.name);
printf("passwd=%s ",temp.passwd);
printf("cmd=%d ",temp.cmd);
printf("revert=%d ",temp.revert);
printf("toname=%s ",temp.toname);
printf("msg=%s ",temp.msg);
printf("flag=%d ",temp.flag);
printf("sockfd=%d ",temp.sockfd);
printf("time=%s ",temp.time);
printf("filename=%s ",temp.filename);
}
int main()
{
time_t timep;
time(&timep);
char*timedata=ctime(&timep);
sqlite3*db=NULL;
char*errmsg;
open_db(&db);//打开数据库
creat_user_db(db,&errmsg);
creat_data_db(db,&errmsg);
creat_online_db(db,&errmsg);
creat_server_db(db,&errmsg);
insert_server_db(db,timedata,&errmsg);//向server数据库插入数据
insert_server();
int lfd;
int cfd;
int sfd;
int rdy;
stChat temp;
struct sockaddr_in sin;
struct sockaddr_in cin;
int client[FD_SETSIZE];/*客户端连接的套接字描述符数组*/
int maxi;
int maxfd;/*大连接数*/
fd_set rset;
fd_set allset;
socklen_t addr_len;/*地址结构长度*/
int i;
int n;
int len;
int opt=1;/*套接字选项*/
char addr_p[20];
mybzero(&sin);
lfd=mysocket();
/*设置套接字选项使用默认选项*/
setsockopt(lfd,SOL_SOCKET,SO_REUSEADDR,&opt,sizeof(opt));
mybind(lfd,&sin); //调用bind函数将serer_addr结构绑定到sockfd上
mylisten(lfd);//开始监听端口等待客户的请求
printf(" 服务器开始等待客户端链接 ");
maxfd=lfd;/*对大文件描述符进行初始化*/
maxi=-1;
/*初始化客户端连接描述符集合*/
for(i=0;i<FD_SETSIZE;i++)
{
client[i]=-1;
}
FD_ZERO(&allset);/*清空文件描述符集合*/
FD_SET(lfd,&allset);/*将监听字设置在集合内*/
/*开始服务程序的死循环*/
while(1)
{
rset=allset;
/*得到当前可以读的文件描述符数*/
rdy=select(maxfd+1,&rset,NULL,NULL,NULL);
if(FD_ISSET(lfd,&rset))
{
addr_len=sizeof(sin);
cfd=myaccept(lfd,&cin,&addr_len);//接受客户端的请求
/*查找一个空闲位置*/
for(i=0;i<FD_SETSIZE;i++)
{//printf("%d ",client[i]);
if(client[i]<=0)
{
client[i]=cfd;/*将处理该客户端的连接套接字设置到该位置*/
break;
}
}
/*太多的客户端连接服务器拒绝俄请求跳出循环*/
if(i==FD_SETSIZE)
{
printf("too many clients");
exit(1);
}
FD_SET(cfd,&allset);/*设置连接集合*/
if(cfd>maxfd)/*新的连接描述符*/
{
maxfd=cfd;
}
if(i>maxi)
{
maxi=i;
}
if(--rdy<=0)/*减少一个连接描述符*/
{
continue;
}
}
/*对每一个连接描述符做处理*/
for(i=0;i<FD_SETSIZE;i++)
{
if((sfd=client[i])<0)
{
continue;
}
if(FD_ISSET(sfd,&rset))
{
printf("客户端sfd=%d已经成功链接 ",sfd);
n=read(sfd,&temp,sizeof(stChat));
if(n==0)
{
printf("客户端sfd=%d已经离开本服务器. ",sfd);
delete_online_db(db,&errmsg,sfd);
fflush(stdout);/*刷新输出终端*/
close(sfd);
FD_CLR(sfd,&allset);/*清空连接描述符数组*/
client[i]=-1;
}
else
{
temp.sockfd=sfd;
/*将客户端地址转换成字符串*/
inet_ntop(AF_INET,&cin.sin_addr,addr_p,sizeof(addr_p));
addr_p[strlen(addr_p)]='
