MFC服务器客户端聊天

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;

}

  • 发表于:
  • 原文链接https://kuaibao.qq.com/s/20190108G1DB5D00?refer=cp_1026
  • 腾讯「云+社区」是腾讯内容开放平台帐号(企鹅号)传播渠道之一,根据《腾讯内容开放平台服务协议》转载发布内容。

同媒体快讯

扫码关注云+社区

领取腾讯云代金券