1.开发软件:VS2017
2.开发语言:C++
3.操作系统:Windows10
3.使用技术:Socket、MFC
二、演示效果 (一)Windows服务端: (二)Windows客户端:基于MFC的客户端效果
控制台客户端效果
①客户端与服务端建立连接
②客户端向服务端发送注册、登录的数据信息。
③服务端验证客户端的信息,向客户端发送是否验证成功的消息。
三、C++程序实现 (一)Socket传输字符串数据I.服务端:
1.创建控制台应用程序:ServerSocket_CSDN
2.服务端程序代码&注释
#define _WINSOCK_DEPRECATED_NO_WARNINGS //防止报错 #includeII.客户端:#include using namespace std; #pragma comment(lib,"ws2_32.lib") int main() { WORD sockVersion = MAKEWORd(2, 2);//调用2.2版本的socket WSADATA wsaData; //WSA(Windows Sockets Asynchronous)异步套接字 //将指定版本的socket与该应用程序绑定 if (WSAStartup(sockVersion, &wsaData) != 0) //返回为0则表示初始化成功 return 0; //AF_INET,使用IPV4通信;SOCK_STREAM,使用流式套接字;IPPROTO_TCP,采用TCP协议 SOCKET serverSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); if (serverSocket == INVALID_SOCKET) //如果创建失败,则输出错误 { cout << "socket error:" << WSAGetLastError() << endl; WSACleanup(); //中止Windows Sockets DLL的使用;与上面WSAStartup()配套使用 return 0; } //创建服务器Socket套接字成功后 sockaddr_in serverAddr; serverAddr.sin_family = AF_INET; //指定协议族,AF_INET<->IPV4;AF_INET6<->IPV6 serverAddr.sin_addr.S_un.S_addr = INADDR_ANY; //指定IP地址 serverAddr.sin_port = htons(8888); //指定端口号 //Socket绑定地址,第二个参数注意需要使用强制转换 if (bind(serverSocket, (SOCKADDR*)&serverAddr, sizeof(serverAddr)) == SOCKET_ERROR) { cout << "Bind Error!" << endl; closesocket(serverSocket); WSACleanup(); return 0; } //建立监听客户端请求的信号,设置最多有5个客户端 if (listen(serverSocket, 5) == SOCKET_ERROR)//如果建立失败 { cout << "Listen Error !" << endl; closesocket(serverSocket); //关闭Socket套接字 WSACleanup(); return 0; } cout << "正在监听..." << endl; //开始不断处理各个客户端请求 while (true) { SOCKET clientSocket = INVALID_SOCKET; //初始化一个客户端socket sockaddr_in clientAddr; //客户端的地址结构 int iAddrLength = sizeof(clientAddr); //求出该结构的长度 cout << "等待登录..." << endl; //接收客户端的连接请求。第一个参数为服务端Socket,第二个参数用来接收从客户端传来的地址,第三个参数为地址结构的长度 clientSocket = accept(serverSocket, (SOCKADDR*)&clientAddr, &iAddrLength);//accept为阻塞函数 if (clientSocket == INVALID_SOCKET) //如果接收失败 { cout << "Accept Error !" << WSAGetLastError() << endl; closesocket(serverSocket); WSACleanup(); return 0; } //inet_ntoa将网络地址转换为字符输出 cout << "客户端地址:" << inet_ntoa(clientAddr.sin_addr) << endl; //开始不断接收该客户端数据 char buffFromClient[1024]; //用于接收客户端传来的数据 while(true) { memset(buffFromClient, 0, sizeof(buffFromClient)); //recv也为阻塞函数,只有客户端发送数据过来后,程序才会往下继续走 int iLenOfRecvData = recv(clientSocket, buffFromClient, sizeof(buffFromClient), 0); if (iLenOfRecvData > 0) //如果接收的数据不为空 { cout << buffFromClient << endl; } else { cout << "服务器断开,无接收..." << endl; break; } char sendToClientBuff[1024] = "服务端收到啦!"; send(clientSocket, sendToClientBuff, sizeof(sendToClientBuff), 0); } closesocket(clientSocket);//关闭与该客户端的套接字 } closesocket(serverSocket);//关闭服务器套接字 WSACleanup(); }
1.新建MFC对话框程序:ClientSocket_CSDN
2.UI设计,添加Button控件
3.实现点击Button控件向服务端发送消息的函数
①在.h文件中添加需要的头文件、库,定义一个全局变量:m_clientSocket。
②修改项目属性,将SDL检查设置为:否,用于防止报错。
③编写OnBnClickedButton1()函数
void CClientSocketCSDNDlg::OnBnClickedButton1()
{
WORD sockVersion = MAKEWORd(2, 2);
WSADATA wsaData;//WSA(Windows Sockets Asynchronous)异步套接字
if (WSAStartup(sockVersion, &wsaData) != 0)
return;
m_clientSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
if (m_clientSocket == INVALID_SOCKET)
{
MessageBox("Invalid Socket!", "错误", MB_ICONERROR);
return;
}
//建立一个客户端地址
sockaddr_in serAddr;
serAddr.sin_family = AF_INET;
serAddr.sin_port = htons(8888);
serAddr.sin_addr.S_un.S_addr = inet_addr("127.1.0.1");
//客户端向服务端请求连接
if (connect(m_clientSocket, (sockaddr*)&serAddr, sizeof(serAddr)) == SOCKET_ERROR)
{
MessageBox("Connect Error!!", "错误", MB_ICONERROR);
closesocket(m_clientSocket);
return;
}
//与服务端连接成功,开发发送消息
char sendToServerBuff[1024] = "服务端,我来啦~";
send(m_clientSocket, *(&sendToServerBuff), sizeof(sendToServerBuff), 0);
//接收服务端返回的消息
char buffFromServer[1024];
int recvDataLen = recv(m_clientSocket, buffFromServer, sizeof(buffFromServer), 0);
if (recvDataLen > 0)
{
MessageBox(buffFromServer);
}
closesocket(m_clientSocket);
WSACleanup();
}
(二)Socket传输结构体数据
(三)Socket传输类对象数据
(四)Socket+Protobuf数据序列化
(未完待续...)



