TCP的4元组

#include "stdafx.h"

#include <WinSock2.h>
#pragma comment(lib, "WS2_32.lib")

#include <windows.h>

#include <string>
#include <iostream>
#include <thread>

#define TEST_PORT 1234

volatile bool bServerListen = false;

// 获取TCP的4元组
bool GetSocketIpPort(SOCKET s, std::string& local_ip, WORD& local_port, std::string& peer_ip, WORD& peer_port)
{
	local_ip = "0.0.0.0";
	local_port = 0;
	peer_ip = "0.0.0.0";
	peer_port = 0;
	struct sockaddr_in sa;
	int len = sizeof(sa);
	getsockname(s, (struct sockaddr *)&sa, &len);
	local_ip = inet_ntoa(sa.sin_addr);
	local_port = htons(sa.sin_port);
	getpeername(s, (struct sockaddr *)&sa, &len);
	peer_ip = inet_ntoa(sa.sin_addr);
	peer_port = htons(sa.sin_port);

	return true;
}


// 服务器函数
int sfun(int PORT)
{
	char msg[1024] = {};

	WSADATA wsaData;
	WORD wVersionRequested = MAKEWORD(2, 2);        //生成版本号
	WSAStartup(wVersionRequested, &wsaData);

	SOCKET sock_server = socket(AF_INET, SOCK_STREAM, 0);

	int addr_len = sizeof(struct sockaddr_in);
	struct sockaddr_in server_addr;
	memset((void*)&server_addr, 0, sizeof(server_addr));
	server_addr.sin_family = AF_INET;
	server_addr.sin_port = htons(PORT);
	server_addr.sin_addr.s_addr = htonl(INADDR_ANY);

	bind(sock_server, (struct sockaddr*)&server_addr, addr_len);

	listen(sock_server, 0);

	bServerListen = true;

	struct sockaddr_in client_addr;
	addr_len = sizeof(sockaddr_in);
	memset((void*)&client_addr, 0, sizeof(client_addr));
	SOCKET newsock = accept(sock_server, (struct sockaddr *)&client_addr, &addr_len);

	std::string local_ip;
	WORD local_port = 0;
	std::string peer_ip;
	WORD peer_port = 0;
	GetSocketIpPort(newsock, local_ip, local_port, peer_ip, peer_port);
	sprintf(msg, "local=%s:%d peer=%s:%d", local_ip.c_str(), local_port, peer_ip.c_str(), peer_port);

	int size1 = send(newsock, msg, strlen(msg)+1, 0);
	Sleep(50);
	int size2 = recv(newsock, msg, sizeof(msg), 0);
	Sleep(50);
	std::cout << "// Recv from Client: " << msg << std::endl;

	bServerListen = false;

	closesocket(sock_server);
	closesocket(newsock);
	WSACleanup();

	return 0;
}

// 客户端函数
int cfun(int PORT)
{
	SOCKET sock_client;
	struct sockaddr_in server_addr;
	int addr_len = sizeof(struct sockaddr_in);
	char msg[1024] = {};
	memset(msg, 0, sizeof(msg));
	
	WSADATA wsaData;
	WORD wVersionRequested = MAKEWORD(2, 2);        //生成版本号
	WSAStartup(wVersionRequested, &wsaData);

	sock_client = socket(AF_INET, SOCK_STREAM, 0);

	char IP[20] = { "127.0.0.1" };

	memset((void*)&server_addr, 0, sizeof(server_addr));
	server_addr.sin_family = AF_INET;
	server_addr.sin_port = htons(PORT);
	server_addr.sin_addr.s_addr = inet_addr(IP);

	connect(sock_client, (struct sockaddr*)&server_addr, addr_len);

	std::string local_ip = "";
	WORD local_port = 0;
	std::string peer_ip = "";
	WORD peer_port = 0;
	GetSocketIpPort(sock_client, local_ip, local_port, peer_ip, peer_port);
	sprintf(msg, "local=%s:%d peer=%s:%d", local_ip.c_str(), local_port, peer_ip.c_str(), peer_port);

	int size1 = send(sock_client, msg, strlen(msg)+1, 0);
	Sleep(100);
	int size2 = recv(sock_client, msg, sizeof(msg), 0);
	Sleep(100);
	std::cout << "// Recv from Server: " << msg << std::endl;

	closesocket(sock_client);
	WSACleanup();

	return 0;
}

// 服务器线程
void server_fun(int port)
{
	sfun(port);
}

// 客户端线程
void client_fun(int port)
{
	cfun(port);
}


int main()
{
	int port = TEST_PORT;
	std::thread server(server_fun, port);

	while (!bServerListen)
	{
		Sleep(100);
	}

	std::thread client(client_fun, port);

	server.join();
	client.join();

	return   0;
}

// 输出
// Recv from Client: local=127.0.0.1:40408 peer=127.0.0.1:1234
// Recv from Server: local=127.0.0.1:1234 peer=127.0.0.1:40408

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值