widows下使用socket套接字进行网络通信的步骤与Linux下差异不大,基本的调用流程也是相似的,即使内部的实现有所不同。
以下是服务器端的代码实现:
#include <iostream>
#include <stdlib.h>
#include <WinSock2.h>
using namespace std;
int main(int argc, char* argv[])
{
if (argc != 2)
{
cout << "invalid parameter! add port!" << endl;
exit(1);
}
WSADATA wsaData;
SOCKET servSock, clntSock;
SOCKADDR_IN servAddr, clntAddr;
int clntAddrLen;
// 设置程序中用到的Winsock版本,并初始化相应版本的库
if (WSAStartup(MAKEWORD(2, 2), &wsaData) != 0)
{
cout << "WSAStartup() error" << endl;
exit(1);
}
// 创建socket套接字
servSock = socket(PF_INET, SOCK_STREAM, 0);
if (servSock == INVALID_SOCKET)
{
cout << "socket() error" << endl;
exit(1);
}
// 设置服务端的地址信息:IP、端口、协议族
memset(&servAddr, 0, sizeof(servAddr));
servAddr.sin_family = AF_INET;
servAddr.sin_addr.s_addr = htonl(INADDR_ANY);
servAddr.sin_port = htons(atoi(argv[1]));
// 绑定IP和端口
if (bind(servSock, (SOCKADDR*)&servAddr, sizeof(servAddr)) == SOCKET_ERROR)
{
cout << "bind() error" << endl;
exit(1);
}
// 在所绑定的端口号做监听
if (listen(servSock, 5) == SOCKET_ERROR)
{
cout << "listen() error" << endl;
exit(1);
}
// 接收来自客户端的连接请求
clntAddrLen = sizeof(clntAddr);
clntSock = accept(servSock, (SOCKADDR*)&clntAddr, &clntAddrLen);
if (clntSock == INVALID_SOCKET)
{
cout << "accept() error" << endl;
exit(1);
}
// 向客户端发送数据
char message[] = "Hello, It's servers!";
send(clntSock, message, sizeof(message), 0);
// 关闭套接字连接
closesocket(servSock);
closesocket(clntSock);
// 注销使用的Winsock库
WSACleanup();
return EXIT_SUCCESS;
}
以下是客户端的代码实现:
#define _WINSOCK_DEPRECATED_NO_WARNINGS
#include <iostream>
#include <stdlib.h>
#include <WinSock2.h>
using namespace std;
int main(int argc, char* argv[])
{
// 检查输入参数的合法性
if (argc != 3)
{
cout << "invalid parameter! add ip and port!" << endl;
exit(1);
}
WSADATA wsaData;
SOCKET clntSocket;
SOCKADDR_IN servAddr;
// 设置程序中用到的Winsock版本,并初始化相应版本的库
if (WSAStartup(MAKEWORD(2, 2), &wsaData) != 0)
{
cout << "WSAStartup() error" << endl;
exit(1);
}
// 创建socket套接字
clntSocket = socket(PF_INET, SOCK_STREAM, 0);
if (clntSocket == INVALID_SOCKET)
{
cout << "socket() error" << endl;
exit(1);
}
// 设置服务器端的地址信息:IP、端口、协议族
memset(&servAddr, 0, sizeof(servAddr));
servAddr.sin_family = AF_INET;
servAddr.sin_addr.s_addr = inet_addr(argv[1]);
servAddr.sin_port = htons(atoi(argv[2]));
// 创建连接
if (connect(clntSocket, (SOCKADDR*)&servAddr, sizeof(servAddr)) == SOCKET_ERROR)
{
cout << "connect() error" << endl;
exit(1);
}
// 接收来自服务器端的数据
char message[100] = { 0 };
int msglen = recv(clntSocket, message, sizeof(message) - 1, 0);
if (msglen == -1)
{
cout << "recv() error" << endl;
exit(1);
}
cout << "msg from server : " << message << endl;
// 关闭套接字连接
closesocket(clntSocket);
// 注销使用的Winsock库
WSACleanup();
return 0;
}
在VS中编译后,生成可执行文件。然后使用cmd,分别运行客户端和服务器端程序,服务器端监听8888端口,而客户端绑定本地IP和8888端口,与服务器端建立链接。
客户端程序执行结果:建立连接成功后,收到来自服务器端的信息数据。
服务器端执行结果:开始时创建套接字,然后等待客户端的连接,没有任何输出,一旦客户端连接成功后,发送消息,然后直接运行结束。
谢谢阅读。