WinSocket实现进程通信的一个简单实例

    Windows下通过Socket可以使进程之间产生通信。

    设计上简单地分为服务端和客户端。


服务端:

  1. 建立Socket
  2. 声明自身的端口号和地址并绑定到Socket
  3. 使用Listen打开监听,然后不断用Accept去查看是否有连接,如果有,捕获Socket,并通过Recv获取消息的内容
  4. 通信完成后调用CloseSocket关闭这个对应Accept到的Socket,如果不再需要等待任何客户端连接,那么用CloseSocket关闭掉自身的Socket 
客户端:
  1. 建立Socket
  2. 通过端口号和地址确定目标服务器,使用Connect连接到服务器
  3. send发送消息,等待处理
  4. 通信完成后调用CloseSocket关闭Socket

服务端代码:
#pragma once

/*
ServerNet.h
服务端:建立Socket,声明自身的端口号和地址并绑定到Socket,使用Listen打开监听,
然后不断用Accept去查看是否有连接,如果有,捕获Socket,并通过Recv获取消息的内容,
通信完成后调用CloseSocket关闭这个对应Accept到的Socket,如果不再需要等待任何客户端连接,那么用CloseSocket关闭掉自身的Socket
*/


#include
#include

#pragma comment(lib, "Ws2_32.lib")

class ServerNet
{
private:
	SOCKET m_sock;
public:
	//  初始化服务器
	int ServerInit(const char* address, int port);

	// 更新数据
	void ServerRun();
};

/*
ServerNet.cpp
*/

#include"ServerNet.h"

/*服务器初始化*/
int ServerNet::ServerInit(const char* address, int port)
{
	int rlt = 0;

	int iErrorMsg;

	//初始化WinSock
	WSAData wsaData;
	iErrorMsg = WSAStartup(MAKEWORD(1, 1), &wsaData);

	if (iErrorMsg != NO_ERROR)
	{
		//初始化WinSock失败
		printf("server wsastartup failed with error : %d\n", iErrorMsg);

		rlt = 1;
		return rlt;
	}

	// 创建服务器端socket

	m_sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
	if (m_sock == INVALID_SOCKET)
		// 创建socket出现了异常
	{
		printf("server socket failed with error: %d\n", WSAGetLastError());
		rlt = 2;
		return rlt;
	}

	// 声明信息
	SOCKADDR_IN	servaddr;
	servaddr.sin_family = AF_INET;
	servaddr.sin_port = port;
	servaddr.sin_addr.s_addr = inet_addr(address);

	//绑定
	iErrorMsg = bind(m_sock, (SOCKADDR*)&servaddr, sizeof(servaddr));
	if (iErrorMsg < 0)
	{
		//绑定失败
		printf("bind failed with error : %d\n", iErrorMsg);
		rlt = 3;
		return rlt;
	}

	return rlt;
}

void ServerNet::ServerRun()
{
	// 公开连接
	listen(m_sock, 5);

	SOCKADDR_IN tcpAddr;
	int len = sizeof(sockaddr);
	SOCKET newSocket;
	char buf[1024];
	int rval;

	do
	{
		// 接收信息
		newSocket = accept(m_sock, (sockaddr*)&tcpAddr, &len);

		if (newSocket == INVALID_SOCKET)
		{
			// 非可用socket
			printf("invalid socket occured.\n");
		}
		else
		{
			// 可用的新socket连接
			printf("new socket connect: %d\n", newSocket);

			// 消息处理
			do
			{
				//printf("process\n");
				// 接收数据
				memset(buf, 0, sizeof(buf));
				rval = recv(newSocket, buf, 1024, 0);

				if (rval == SOCKET_ERROR)
					// 该异常通常发生在未closeSocket就退出时
				{
					printf("recv socket error.\n");
					break;
				}
					
				else if (rval == 0)
					// 0表示正常退出
					printf("socket %d connect end.\n", newSocket);
				else
					// 显示接收到的数据
					printf("recv msg: %s\n", buf);
			} while (rval != 0);

			// 关于接收的socket
			closesocket(newSocket);
		}
	} while (1);

	// 关闭自身socket
	closesocket(m_sock);
}


#include"ServerNet.h"

int main()
{
	ServerNet serverNet;
	int iRlt = serverNet.ServerInit("127.0.0.1", 8888);
	if (iRlt == 0)
	{
		printf("servr init successful.\n");
		serverNet.ServerRun();
	}
	else
		printf("server init failed with error: %d\n", iRlt);
	system("pause");
}


客户端代码:
#pragma once

/*
ClinetNet.h
客户网络
*/

#include
#include

#pragma comment(lib, "Ws2_32.lib")

class ClientNet
{
private:
	SOCKET m_sock;

public:
	// 连接指定的服务器
	int ClientConnect(int port, const char* address);
	// 发送信息
	int ClientSend(const char* msg, int len);
	// 关闭连接
	void ClientClose();
};


/*
ClientNet.cpp
*/

#include"ClientNet.h"

/*客户端Socket连接*/
int ClientNet::ClientConnect(int port, const char* address)
{
	int rlt = 0;   //connectflag  0-success 1-WSAStartfailed 2-socketfailed 3-connectfailed

	// 记录错误信息
	int iErrMsg;
	// 启动WinSock
	WORD wVersionRequested;
	WSADATA wsaData;
	wVersionRequested = MAKEWORD(1, 1);
	iErrMsg = WSAStartup(wVersionRequested, &wsaData);
	if (iErrMsg != NO_ERROR)
		// WSAStartup出现了错误
	{
		printf("failed with WSAStartup error: %d\n", iErrMsg);
		rlt = 1;
		return rlt;
	}

	// 创建Socket
	m_sock = socket(AF_INET, SOCK_STREAM, 0);
	if (m_sock==INVALID_SOCKET)
		// socket出现了错误
	{
		printf("failed with socket error: %d\n", WSAGetLastError());
		rlt = 2;
		return rlt;
	}


	// 目标服务器数据
	SOCKADDR_IN servaddr;
	servaddr.sin_family = AF_INET;
	servaddr.sin_port = port;
	servaddr.sin_addr.s_addr = inet_addr(address);

	// sock与目标服务器连接
	iErrMsg = connect(m_sock, (SOCKADDR*)&servaddr, sizeof(servaddr));
	if (iErrMsg != NO_ERROR)
	{
		printf("failed with connect error: %d\n", iErrMsg);
		rlt = 3;
		return rlt;
	}

	// success
	return rlt;

}

/*客户端发送消息*/
int ClientNet::ClientSend(const char* msg, int len)
{
	int rlt = 0;

	int iErrMsg = 0;

	// 指定sock发送消息
	iErrMsg = send(m_sock, msg, len, 0);
	if (iErrMsg < 0)
		// 发送失败
	{
		printf("send msg failed with error: %d\n", iErrMsg);
		rlt = 1;
		return rlt;
	}
	printf("send msg successfully\n");
	return rlt;
}

/*客户端关闭Socket*/
void ClientNet::ClientClose()
{
	closesocket(m_sock);
}

#include
#include
#include"ClientNet.h"

using namespace std;

int main()
{
	ClientNet client;
	int rlt = 0;
	string msg;
	//memset(msg, 0, sizeof(msg));

	//连接到127.0.0.1(即本地),端口号为8888的服务端
	printf("connecting.....\n");
	rlt = client.ClientConnect(8888, "127.0.0.1");

	if (rlt == 0)
		// socket连接成功
	{
		//发送消息
		printf("	connect successfully. input  q to quit\n");
		printf("-------------------------\n");
		while (1)
		{
			printf("msg input: ");
			getline(cin, msg);
			if (msg == "q")
				break;
			else
			{
				printf("sending msg.....\n");
				rlt = client.ClientSend(msg.c_str(), msg.length());
			}
			
		}
		

		// 关闭socket
		printf("closing socket.....\n");
		client.ClientClose();


	}

	system("pause");

	return 0;

}


通信示例如下图:

WinSocket实现进程通信的一个简单实例_第1张图片



你可能感兴趣的:(Socket)