最简单的CSocket通信流程
最简单的CSocket通信是一个只有客户端向服务器端发信息的单向通信。器双方Socket之间的关系如下图所示:
由上面这个十分简单的过程很容易得出最简单的Socket通信流程,如下图所示:
要实现这样一个完整流程需要三个套接字对象:客户端一个,服务器端两个(一个用于监听,另一个用于接收客户端发来的信息)。
具体代码实现如下:
服务器端
在OnInitDialog()函数添加如下代码,用于创建线程,接收客户端发送的信息。
HANDLE hThread;
hThread = CreateThread(NULL, 0, StartServer, (LPVOID)this, 0, NULL); //创建线程:接收客户端发送的信息
CloseHandle(hThread);
添加全局函数(线程函数)
DWORD WINAPI StartServer(LPVOID lParam)
{
if (!AfxSocketInit())
{
AfxMessageBox(IDP_SOCKETS_INIT_FAILED);
return 1;
}
CDlgTestDlg *aDlg = (CDlgTestDlg *)lParam;
CString strPort = "2000";
UINT nPort = atoi(strPort);
CString strText;
//socket------------------------------------------------
CSocket aSocket, serverSocket;
//创建接收端Socket
if (!aSocket.Socket())
{
char szError[256] = {0};
sprintf(szError, "创建套接字失败: %d", GetLastError());
AfxMessageBox(szError);
return 1;
}
BOOL bOptVal = TRUE;
int bOptLen = sizeof(BOOL);
aSocket.SetSockOpt(SO_REUSEADDR, (void *)&bOptVal, bOptLen, SOL_SOCKET);
if (!aSocket.Bind(nPort))
{
char szError[256] = {0};
sprintf(szError, "绑定失败: %d", GetLastError());
AfxMessageBox(szError);
return 1;
}
if(!aSocket.Listen(10))
{
char szError[256] = {0};
sprintf(szError, "监听失败: %d", GetLastError());
AfxMessageBox(szError);
return 1;
}
aDlg->GetDlgItemText(IDC_EDIT_SHOW, strText);
strText += "Server Start! \r\n";
aDlg->SetDlgItemText(IDC_EDIT_SHOW, strText);
while(1)
{
if(!aSocket.Accept(serverSocket))
{
continue;
}
else
{
char szRecvMsg[256] = {0};
char szOutMsg[256] = {0};
serverSocket.Receive(szRecvMsg, 256);
sprintf(szOutMsg, "%s : %s \r\n", strPort, szRecvMsg);
aDlg->GetDlgItemText(IDC_EDIT_SHOW, strText);
strText = szOutMsg + strText;
aDlg->SetDlgItemText(IDC_EDIT_SHOW, strText);
serverSocket.Send("成功接收数据!", 50);
serverSocket.Close();
}
Sleep(10);
}
aSocket.Close();
serverSocket.Close();
return 0;
}
客户端
添加按钮控件,并在按钮响应函数中添加如下代码:
void CDlgTestClientDlg::OnBtnSend()
{
// TODO: Add your control notification handler code here
AfxSocketInit();
CSocket aSocket;
CString strIP = "127.0.0.1"; //IP地址
CString strPort = "2000"; //端口号
CString strSendMsg = "";
CString strText;
if(!aSocket.Create())
{
char szMsg[1024] = {0};
sprintf(szMsg, "create faild: %d", aSocket.GetLastError());
AfxMessageBox(szMsg);
return;
}
this->GetDlgItemText(IDC_EDIT_WRITE, strSendMsg);
if(strSendMsg=="")
{
AfxMessageBox("空字符串,不能发送!");
return;
}
int nPort = atoi(strPort);
if(aSocket.Connect(strIP, nPort))
{
char szRecValue[1024] = {0};
aSocket.Send(strSendMsg, strSendMsg.GetLength());
this->SetDlgItemText(IDC_EDIT_WRITE, "");
aSocket.Receive((void *)szRecValue, 1024);
sprintf(szRecValue, "%s \r\n", szRecValue);
this->GetDlgItemText(IDC_EDIT_SHOW, strText);
strText = szRecValue + strText;
this->SetDlgItemText(IDC_EDIT_SHOW, strText);
}
else
{
char szMsg[1024] = {0};
sprintf(szMsg, "create faild: %d", aSocket.GetLastError());
AfxMessageBox(szMsg);
}
aSocket.Close();
return;
}
以上完成了一个简单的Socket单向通信流程,只有客户端向服务器端发送信息。