一个最简单的服务端和客户端(用CSocket)

时间:2022-07-22 05:23:29

功能:服务器端程序处于监听状态,等待客户端连接。客户端发来数据后,服务端回发一个消息,同时关闭连接!

源码下载

服务器(采用一个监听线程)核心代码:

BOOL CListenThread::InitInstance()
{
// if (!AfxSocketInit())
// {
// AfxMessageBox(IDP_SOCKETS_INIT_FAILED);
// return FALSE;
// }
m_bListening = TRUE; // 线程启动时默认处于监听状态
while(1)
{
if(m_bListening)
{
StartListen();
}
}

return TRUE;
}

int CListenThread::ExitInstance()
{
StopListen();

return CWinThread::ExitInstance();
}

BOOL CListenThread::StartListen()
{
CString sResult;
try
{
if(m_pListenSocket == NULL)
m_pListenSocket = new CSocket;
if(m_pListenSocket && m_pListenSocket->Create(m_nPort)) // Create()内部包含了Bind()
{
m_pListenSocket->Listen();
m_pMainDlg->ShowInfo("启动监听成功");
PostMessage(m_pMainDlg->GetSafeHwnd(), WM_ENABLE_LISTENING, 0, 0);
while(1)
{
CSocket clientSocket;
if(m_pListenSocket->Accept(clientSocket))
{
char buffer[1024] = {0};
CString sText;
clientSocket.Receive(buffer, 1024);
sText = buffer;
m_pMainDlg->ShowInfo(sText);

CString s = "Thank you, JoeBlack";
clientSocket.Send(s, s.GetLength());
// send(clientSocket.m_hSocket, s, s.GetLength(), 0); // 与上一句等效

if(sText == "close") // stop listening
{
StopListen();
break;
}
else if(sText == "quit") // post a message to let the main thread delete listen-thread
{
EndMyThread();
return TRUE;
}
}
}
return TRUE;
}
}
catch (CException* e)
{
char str[300] = {0};
e->GetErrorMessage(str, 300);
sResult.Format("启动监听失败,错误码:%d", str);
m_pMainDlg->ShowInfo(sResult);
}
catch(...)
{
int err;
err = WSAGetLastError();
sResult.Format("启动监听失败,错误码:%d", err);
m_pMainDlg->ShowInfo(sResult);
}
m_bListening = FALSE;

return FALSE;
}

BOOL CListenThread::StopListen() // 停止服务器监听
{
if(m_pListenSocket)
{
m_pListenSocket->Close();
delete m_pListenSocket;
m_pListenSocket = NULL;
m_pMainDlg->ShowInfo("Stop listening successful");
m_bListening = FALSE;
m_pMainDlg->PostMessage(WM_ENABLE_LISTENING, 1, 0); // 让“启动监听”按钮变为可用
}
return TRUE;
}

BOOL CListenThread::EndMyThread() // 关闭CSocket并退出本线程
{
StopListen();
m_pMainDlg->ShowInfo("Exit from Listen-Thread");
PostMessage(m_pMainDlg->GetSafeHwnd(), WM_FREE_LISTENTHREAD, 0, 0);

return TRUE;
}

服务端程序实现监听,当收到close或quit时,会停止监听,这时客户端即使发来数据,也不会被收到。服务器端点击窗口中的“开启监听”后,可以重新开启监听线程。

客户端程序(向server发送消息并接收返回值):

void CClientAppDlg::OnBtnSend()
{
CSocket sendSocket;
if(sendSocket.Create())
{
if(sendSocket.Connect("127.0.0.1", 5050))
{
UpdateData();
sendSocket.Send(m_strEdit, m_strEdit.GetLength());
Sleep(100); // 等待服务器端数据返回

char buf[1024] = {0};
CString sResponse;
while(sendSocket.Receive(buf, 1024))
//while(recv(sendSocket, buf, 1024, 0))
{
sResponse += buf;
}

MessageBox(sResponse);
sendSocket.Close();
}
}
}