#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