void ServerConfig::Listen(int iPort){
dialog = m_pDialog;
if(WSAStartup(MAKEWORD(2, 2), &wsadata) != 0){
CString errorMessage;
errorMessage.Format(_TEXT("WSAStartup error : %d"), WSAGetLastError());
if(m_pDialog != NULL){
m_pDialog->DisplayConnectErrorMessage(errorMessage);
}
return ;
}
//创建流式套接字
if((s = socket(AF_INET, SOCK_STREAM, 0)) == INVALID_SOCKET){
CString errorMessage;
errorMessage.Format(_TEXT("create socket error : %d"), WSAGetLastError());
if(m_pDialog != NULL){
m_pDialog->DisplayConnectErrorMessage(errorMessage);
}
}
//构造服务器端地址
server_addr.sin_family = AF_INET; // 使用IPV4地址
server_addr.sin_addr.s_addr = INADDR_ANY; // 使用任何地址
server_addr.sin_port = htons(iPort); // 设置端口号
//将地址绑定到Socket套接字上
if(bind(s, (struct sockaddr * )&server_addr, sizeof(server_addr)) == SOCKET_ERROR){
CString errorMessage;
errorMessage.Format(_TEXT("bind error : %d"), WSAGetLastError());
if(m_pDialog != NULL){
m_pDialog->DisplayConnectErrorMessage(errorMessage);
}
exit(EXIT_FAILURE);
}
// 可以同时监听100个连接
listen(s, 100);
// 连接后,获取新的Socket套接字
char * message;
c = sizeof(struct sockaddr_in);
// 每得到一个连接,就生成一个连接套接字
while((new_socket = accept(s, (struct sockaddr *)&client_addr, &c)) != INVALID_SOCKET){
socklen_t len;
struct sockaddr_storage addr;
char cIpstr[INET6_ADDRSTRLEN];
int port;
len = sizeof(addr);
// 获得连接套接字的外地协议地址
getpeername(new_socket,(struct sockaddr *)&addr, &len);
// 处理IPV4
if(addr.ss_family == AF_INET){
struct sockaddr_in *s =(struct sockaddr_in *)&addr;
port = ntohs(s->sin_port);
inet_ntop(AF_INET, &s->sin_addr, cIpstr, sizeof cIpstr);
}
CWinThread *cTh = AfxBeginThread(DataThreadFunc, (LPVOID)new_socket);
}
if(new_socket == INVALID_SOCKET){
CString errorMessage;
errorMessage.Format(_TEXT("new_socket error:%d"), WSAGetLastError());
if(m_pDialog != NULL){
//m_pDialog->DisplayConnectErrorMessage(errorMessage);
}
return ;
}
}
// 一个线程的具体处理
UINT __cdecl ServerConfig::DataThreadFunc(LPVOID pParam){
SOCKET sSocket = reinterpret_cast(pParam);
char * message;
char server_reply[4096];
int recv_size;
CMainFrame* m_pMainWnd;
m_pMainWnd =(CMainFrame *)AfxGetMainWnd();
while((recv_size = recv(sSocket, server_reply, 4096, 0)) != SOCKET_ERROR){
string type, data;
server_reply[recv_size] = '\0';
char *buf;
char *sst = strtok_s(server_reply,":",&buf);
if(sst != NULL){
type = sst;
data = buf;
}
if(type == "注册信息"){
char *sst_register = strtok((char *)data.c_str(),",");
if(sst_register != NULL){
string username = sst_register;
sst_register = strtok(NULL,",");
string password = sst_register;
g_criSection.Lock();
list::iterator info_it;
for(info_it = memberList.begin(); info_it != memberList.end(); info_it++){
if(info_it->username == username){
message = "注册结果:用户名重复";
send(sSocket,message, strlen(message), 0 );
break;
}
}
if(info_it == memberList.end()){
string password_substr = password.substr(0,password.size()-1);
CInfoFile file;
file.AddUser((CString)username.c_str(),(CString)password_substr.c_str());
file.WirteUser();
file.ReLoadMember();
memberList.clear();
list::iterator info_it_new;
for(info_it_new = file.info_member_list.begin(); info_it_new != file.info_member_list.end(); info_it_new++){
info_member info_member_tmp;
info_member_tmp.id = info_it_new->id;
info_member_tmp.username = info_it_new->username;
info_member_tmp.password = info_it_new->password;
info_member_tmp.socket = info_it_new->socket;
info_member_tmp.isOnline = info_it_new->isOnline;
info_member_tmp.chatRoomNum = info_it_new->chatRoomNum;
memberList.push_back(info_member_tmp);
}
message = "注册结果:注册成功";
send(sSocket,message, strlen(message), 0 );
g_criSection.Unlock();
closesocket(sSocket);
return 0;
}
}
}else if(type == "登录信息"){
char *sst_login = strtok((char *)data.c_str(),",");
if(sst_login != NULL){
string username = sst_login;
sst_login = strtok(NULL,",");
string password = sst_login;
g_criSection.Lock();
list::iterator info_it;
for(info_it = memberList.begin(); info_it != memberList.end(); info_it++){
if(info_it->username == username){
string password_substr = password.substr(0,info_it->password.size());
if(info_it->password == password_substr ){
if(info_it->isOnline == "是"){
message = "登录结果:该用户已登陆";
send(sSocket,message, strlen(message), 0 );
break;
}
info_it->socket = sSocket;
info_it->isOnline = "是";
info_it->chatRoomNum = 0;
list::iterator info_it_init;
string sMessage;
for(info_it_init = memberList.begin(); info_it_init != memberList.end(); info_it_init++){
type = "初始化信息";
int chatRoomNum = info_it_init->chatRoomNum;
char tmp_int[12];
itoa(chatRoomNum, tmp_int, 10);
string sChatRoomNum = tmp_int;
sMessage = type+":"+info_it_init->username +","+info_it_init->isOnline+","+ sChatRoomNum;
send(sSocket,sMessage.c_str(), strlen(sMessage.c_str()),0);
Sleep(10);
}
Sleep(10);
string initResult = "初始化完成";
sMessage = type+":"+initResult;
send(sSocket,sMessage.c_str(), strlen(sMessage.c_str()),0);
string type = "添加聊天室";
sMessage = type+":"+maxChatRoomNum;
send(sSocket,sMessage.c_str(), strlen(sMessage.c_str()),0);
Sleep(10);
message = "登录结果:登录成功";
send(sSocket,message, strlen(message), 0 );
break;
}
}
}
if(info_it == memberList.end()){
message = "登录结果:登录失败";
send(sSocket,message, strlen(message), 0 );
}
g_criSection.Unlock();
}
}else if(type == "进入聊天室"){
g_criSection.Lock();
int chatRoomNum = atoi((char *)data.c_str());
list::iterator info_it;
for(info_it = memberList.begin(); info_it != memberList.end(); info_it ++){
if(info_it->socket == sSocket && (info_it->chatRoomNum ==0 ||info_it->chatRoomNum!= chatRoomNum)){
info_it->chatRoomNum = chatRoomNum;
list::iterator info_it_update;
string type = "更新信息";
string message = type+":"+info_it->username+","+info_it->isOnline+","+data;
for(info_it_update = memberList.begin(); info_it_update != memberList.end(); info_it_update ++){
if(info_it_update->isOnline=="是" && info_it_update->socket!=NULL){
send(info_it_update->socket,message.c_str(), strlen(message.c_str()), 0 );
Sleep(10);
}
}
}
}
g_criSection.Unlock();
}else if(type == "公共消息"){
char* buf;
char *sst_publicMessage = strtok_s((char *)data.c_str(),":",&buf);
if(sst_publicMessage != NULL){
string username = sst_publicMessage;
string sData = buf;
g_criSection.Lock();
list::iterator info_it,info_it_send;
for(info_it = memberList.begin(); info_it != memberList.end(); info_it ++){
if(info_it->username == username){
char tmp_chatRoomNum[12];
itoa(info_it->chatRoomNum, tmp_chatRoomNum, 10);
string localChatRoomNum = tmp_chatRoomNum;
string sMessage = type+":"+localChatRoomNum+":"+username+":"+sData;
for(info_it_send = memberList.begin(); info_it_send != memberList.end(); info_it_send ++){
if(info_it_send->isOnline == "是" && info_it_send->chatRoomNum == info_it->chatRoomNum){
if(send(info_it_send->socket, sMessage.c_str(), strlen(sMessage.c_str()), 0)
dialog->DisplayConnectErrorMessage(TEXT("Send failed"));
g_criSection.Unlock();
}
}else if(type == "系统信息"){
if(data == "客户端关闭"){
list::iterator info_it;
for(info_it = memberList.begin(); info_it != memberList.end(); info_it++){
if(info_it->socket == sSocket){
info_it->isOnline = "否";
info_it->socket = NULL;
info_it->chatRoomNum = -1;
closesocket(sSocket);
return 0;
}
}
}
}else if(type == "私人消息"){
char* buf_private;
char *sst_private = strtok_s((char *)data.c_str(),":",&buf_private);
if(sst_private != NULL){
string sendName = sst_private;
sst_private = strtok_s(NULL,":",&buf_private);
string recvName = sst_private;
string sendMessage = buf_private;
list::iterator info_it;
for(info_it = memberList.begin(); info_it != memberList.end(); info_it++){
string type = "私人消息";
string sMessage = type+":"+sendName+":"+recvName+":"+sendMessage;
if(info_it->username == recvName){
if(send(info_it->socket, sMessage.c_str(), strlen(sMessage.c_str()), 0)
dialog->DisplayConnectErrorMessage(TEXT("Send failed"));
}
}
if(info_it->username == sendName){
if(send(info_it->socket, sMessage.c_str(), strlen(sMessage.c_str()), 0)
dialog->DisplayConnectErrorMessage(TEXT("Send failed"));
return 0;
}
领取专属 10元无门槛券
私享最新 技术干货