📄 server.cpp
字号:
#include <sys/ioctl.h>#include <signal.h>#include <unistd.h>#include <fcntl.h>#include <iostream>#include <stdlib.h>#include <stdio.h>#include "List.h"#include <errno.h>
#include "AnEn.h"#include "CWSocket.h"#include <string>#include <sys/types.h>#include <sys/stat.h>#include <netinet/in.h>#include <arpa/inet.h>#include <sys/wait.h>
#include "session.h"#define MYPORT 3490#define BACKLOG 1000using namespace std;
//socket链表的节点typedef struct tagUserSocket{ int userid; int socketid; struct tagUserSocket * next;}UserSocket;
int sigflag = 0;
/***************************************************
函数名:SocketDelete
函数功能:在已经链接的socket链表中,删除制定的socket
函数参数:socket链表头指针,要删除的socket号
返回值:成功为1,失败为0
***************************************************/
int SocketDelete(UserSocket * &p_head, int u_socket, UserSocket * &p_temp)
{
UserSocket * front = p_head;
UserSocket * current = p_head;
int result = 0;
while(current != NULL)
{
if(current->socketid == u_socket && current == p_head)
{
p_head = current->next;
delete current;
result = 1;
break;
}
if(current->socketid == u_socket && current != p_head)
{
if(current == p_temp) { p_temp = current->next; } front->next = current->next;
delete current;
result = 1;
break;
}
front = current;
current = current->next;
}
return result;
}
void handle(int m){ if(m == SIGPIPE) { sigflag = 1; cout<< "sigpipe error"<< endl; } else { sigflag = 0; }}/**********************************
函数名:主函数
功能:实现sever的主控
**********************************/
int main(){ int socketfd;//用于监听的 CWSocket s_socket;//用于发,接消息 UserSocket * SocketHead = NULL; //已链接的socket链表的头指针 UserSocket * SocketCur = NULL; //socket链表的当前访问指针 UserSocket * SocketTemp = NULL; //接收new出来的socket链表节点
Session * newsession = NULL; //用于接收new出来的session
SessionList sess_list; //session链表对象,实现链表的各种操作
CMessage * p_m = NULL; //消息接收指针,用于存放消息,以及获得消息的信息
int MAX = 0; //userid的最大值,用于用户注册分配id以及控制循环
int * sess_socket = NULL; //用于new出来session中的socket数组 char * p_contact = NULL; //用于接收好友列表转换成的字符串 CEncapsulation * Mess; //用于初始化send用的消息 List * UserManage = NULL; //usermanage链表 List * UserOnline = new (List); //在线用户的链表 List * UserConnect = NULL; //用户好友的链表 int sessnum = 0; //用于session的创建 int listlen = 0; //获得链表长度
int k = 0; //用于循环 fd_set readfd; //用于select int filefd = -1; //靠靠靠 struct sockaddr_in my_addr; int as = 0; char filename[20]; struct sockaddr_in their_addr; int * sin_size; int i = 0; int socknum = 0; int tempsocket = -1; //用于socket的分配控制 int tempuserid = -1; int devide = 0; int sesscount = 0; int left = 0; sin_size = &i;
signal(SIGPIPE, handle); if((socketfd = socket(AF_INET, SOCK_STREAM, 0)) == -1) { perror("socket"); exit(1); } my_addr.sin_family = AF_INET; my_addr.sin_port = htons(MYPORT); my_addr.sin_addr.s_addr = INADDR_ANY; bzero(&(my_addr.sin_zero), 8); if(bind(socketfd, (struct sockaddr *)&my_addr, sizeof(struct sockaddr)) == -1) { perror("bind"); exit(1); } FD_ZERO(&readfd); if(listen(socketfd, BACKLOG) == -1) { perror("listen"); exit(1); } SocketCur = SocketHead; UserManage = readUser(); cout<< get_List_longth(UserManage)<< endl; while(1) { SocketCur = SocketHead; SocketTemp = SocketHead; FD_SET(socketfd, &readfd); while(SocketCur != NULL) { FD_SET(SocketCur->socketid, &readfd); SocketCur = SocketCur->next; } SocketTemp = NULL; if(select(1002, &readfd, NULL, NULL, 0) < 0) { perror("select"); exit(1); } (*sin_size) = sizeof(struct sockaddr_in); if(FD_ISSET(socketfd, &readfd)) {
if(socknum <= 1000)
{ SocketTemp = new(UserSocket); while(SocketTemp == NULL) { SocketTemp = new(UserSocket); } SocketTemp->next = NULL; if((SocketTemp->socketid = accept(socketfd, (struct sockaddr *)&their_addr, (socklen_t *)sin_size)) == -1) { perror("accept"); continue; } SocketTemp->next = SocketHead; SocketHead = SocketTemp; cout<< "server got connection from "<< inet_ntoa(their_addr.sin_addr)<< endl; socknum++;
}
else
{
} } SocketCur = SocketHead;
// UserManage = readUser(); while(SocketCur != NULL) { SocketTemp = SocketCur->next; if(FD_ISSET(SocketCur->socketid, &readfd)) { ioctl(SocketCur->socketid, FIONREAD, &as); if( as == 0) { goto loop1; } else { s_socket.Recv(SocketCur->socketid, p_m); switch(p_m->GetType()) { case 1://用户登陆处理 //if((find_Online_In(UserOnline, p_m->GetUID()) == NULL)&&(find_User_In(UserManage, p_m->GetUID(), p_m->GetPWD()) != NULL)) if(find_User_In(UserManage, p_m->GetUID(), p_m->GetPWD()) != NULL) { if(find_Online_In(UserOnline, p_m->GetUID()) != NULL) { tempuserid = p_m->GetUID(); tempsocket = get_Sockfd(UserOnline, tempuserid); SocketDelete(SocketHead, tempsocket, SocketTemp); close(tempsocket); socknum--; delete_Online_Node(UserOnline, tempuserid); tempsocket = -1; tempuserid = -1; } cout<< "the user "<<p_m->GetName()<< " is login successful!"<< endl; if((UserOnline = insert_Online_Node(UserOnline, p_m->GetUID(), SocketCur->socketid)) != NULL) cout<< "the user is insert the online list"<< endl; else cout<< "online list is error"<< endl; SocketCur->userid = p_m->GetUID(); UserConnect = readUserBase(p_m->GetUID()); if(UserConnect != NULL) cout<< "the user connect is ok"<< endl;
p_contact = get_Contact_List(UserOnline, p_m->GetUID()); listlen = get_List_longth(UserConnect); cout<< "there are "<< get_List_longth(UserOnline)<< " persons online!!"<< endl; delete_List(UserConnect); cout<< "the user connect list length is:"<< listlen<< endl; MAX = get_Last_UserId(UserManage);
k = 0;
while(k <= MAX)
{
if(find_Contact_In(p_m->GetUID(), k) == 1)
{ if(find_Online_In(UserOnline, k) != NULL) { Mess = new CEncapsulation(2, p_m->GetUID(), p_m->GetName(), 0);
s_socket.Send(get_Sockfd(UserOnline, k), Mess); if(sigflag == 1) { SocketDelete(SocketHead, get_Sockfd(UserOnline, k), SocketTemp); close(get_Sockfd(UserOnline, k)); socknum--; delete_Online_Node(UserOnline, k); sigflag = 0; } delete Mess; } }
k++;
}
Mess = new CEncapsulation(6, 0, listlen*31, p_contact); delete p_contact; p_contact = Mess->GetContent(); cout<< p_contact<< endl; p_contact = NULL; s_socket.Send(SocketCur->socketid, Mess);
if(sigflag == 1) { tempsocket = SocketCur->socketid; tempuserid = SocketCur->userid; SocketDelete(SocketHead, SocketCur->socketid, SocketTemp); close(tempsocket); socknum--; delete_Online_Node(UserOnline, tempuserid); tempsocket = -1; tempuserid = -1; sigflag = 0; } delete Mess;
Mess = NULL; delete p_m; p_m = NULL; } else { Mess = new CEncapsulation(11, 0, 6, "error"); s_socket.Send(SocketCur->socketid, Mess); delete Mess; Mess = NULL; tempsocket = SocketCur->socketid; SocketDelete(SocketHead, SocketCur->socketid, SocketTemp); close(tempsocket); tempsocket = -1; socknum--; sigflag = 0; delete p_m;
p_m = NULL; } break; case 3://用户退出消息
loop: MAX = get_Last_UserId(UserManage);
k = 0; tempsocket = SocketCur->userid; while(k <= MAX)
{
if(find_Contact_In(SocketCur->userid, k) == 1)
{ //在所有和这个人有关的session中广播session下线刷新
if(find_Online_In(UserOnline, k) != NULL) { Mess = new CEncapsulation(3, SocketCur->userid, "out", 0);
s_socket.Send(get_Sockfd(UserOnline, k), Mess);
if(sigflag == 1) { SocketDelete(SocketHead, get_Sockfd(UserOnline, k), SocketTemp); close(get_Sockfd(UserOnline, k)); socknum--; delete_Online_Node(UserOnline, k); sigflag = 0; } delete Mess;
Mess = NULL; } } k++;
}
cout<< "the "<< SocketCur->userid<< " is exit!!"<< endl; SocketDelete(SocketHead, get_Sockfd(UserOnline, SocketCur->userid), SocketTemp); close(get_Sockfd(UserOnline, tempsocket)); socknum--; delete_Online_Node(UserOnline, tempsocket);
cout<< "the online list length is "<< get_List_longth(UserOnline)<< endl; tempsocket = -1; delete p_m;
p_m = NULL;
break;
case 7:
if(find_Online_In(UserOnline, p_m->GetSID()) != NULL) {
cout<< "a massage from "<< SocketCur->userid<< " to "<< p_m->GetSID()<<endl;
Mess = new CEncapsulation(7, SocketCur->userid, p_m->GetLMCount(), p_m->GetMessage());
s_socket.Send(get_Sockfd(UserOnline, p_m->GetSID()), Mess);
if(sigflag == 1) { tempuserid = p_m->GetSID(); tempsocket = get_Sockfd(UserOnline, tempuserid); SocketDelete(SocketHead, tempsocket, SocketTemp); close(tempsocket); socknum--; delete_Online_Node(UserOnline, tempuserid); tempsocket = -1; tempuserid = -1; sigflag = 0; } delete Mess;
Mess = NULL; }
else { Mess = new CEncapsulation(3, p_m->GetSID(), "OUT", 0); s_socket.Send(SocketCur->socketid, Mess); if(sigflag == 1) { tempuserid = SocketCur->userid; tempsocket = SocketCur->socketid; SocketDelete(SocketHead, tempsocket, SocketTemp); close(tempsocket); socknum--; delete_Online_Node(UserOnline, tempuserid); tempsocket = -1; tempuserid = -1; sigflag = 0; } delete Mess; Mess = NULL; } delete p_m;
p_m = NULL;
break;
case 25: if(find_Online_In(UserOnline, p_m->GetSID()) != NULL) {
cout<< "a massage from "<< SocketCur->userid<< " to "<< p_m->GetSID()<< " to send a file!"<< endl;
Mess = new CEncapsulation(25, SocketCur->userid, p_m->GetLMCount(), p_m->GetMessage());
s_socket.Send(get_Sockfd(UserOnline, p_m->GetSID()), Mess);
if(sigflag == 1) { tempuserid = p_m->GetSID(); tempsocket = get_Sockfd(UserOnline, tempuserid); SocketDelete(SocketHead, tempsocket, SocketTemp); close(tempsocket); socknum--; delete_Online_Node(UserOnline, tempuserid); tempsocket = -1; tempuserid = -1; sigflag = 0; } delete Mess;
Mess = NULL; }
else { Mess = new CEncapsulation(3, p_m->GetSID(), "OUT", 0); s_socket.Send(SocketCur->socketid, Mess); if(sigflag == 1) { tempuserid = SocketCur->userid; tempsocket = SocketCur->socketid; SocketDelete(SocketHead, tempsocket, SocketTemp); close(tempsocket); socknum--; delete_Online_Node(UserOnline, tempuserid); tempsocket = -1; tempuserid = -1; sigflag = 0; } delete Mess; Mess = NULL; } delete p_m;
p_m = NULL; break; case 26: if(find_Online_In(UserOnline, p_m->GetSID()) != NULL) {
cout<< "a massage from "<< SocketCur->userid<< " to "<< p_m->GetSID()<< " refuse to recv!"<< endl;
Mess = new CEncapsulation(26, SocketCur->userid, p_m->GetLMCount() , p_m->GetMessage());
s_socket.Send(get_Sockfd(UserOnline, p_m->GetSID()), Mess);
if(sigflag == 1) { tempuserid = p_m->GetSID(); tempsocket = get_Sockfd(UserOnline, tempuserid); SocketDelete(SocketHead, tempsocket, SocketTemp); close(tempsocket); socknum--; delete_Online_Node(UserOnline, tempuserid); tempsocket = -1; tempuserid = -1; sigflag = 0; } delete Mess;
Mess = NULL; }
else { Mess = new CEncapsulation(3, p_m->GetSID(), "OUT", 0); s_socket.Send(SocketCur->socketid, Mess); if(sigflag == 1) { tempuserid = SocketCur->userid; tempsocket = SocketCur->socketid; SocketDelete(SocketHead, tempsocket, SocketTemp);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -