// server
// .h
#pragma once
#include <WinSock2.h>
typedef void(*pRecvMsgProc)(void* pParam);
class CMySocket
{
public:
CMySocket(SOCKET sock = INVALID_SOCKET);
~CMySocket();
BOOL Create(int nSockFamily = AF_INET, int nSockType = SOCK_STREAM, int nProtocol = 0,
LPCTSTR strIP = nullptr, UINT* pPort = nullptr);
BOOL Listen(int backlog = SOMAXCONN) { return !listen(m_hSocket, backlog); }
BOOL Connect(LPCTSTR lpszHostAddress, UINT nHostPort);
CMySocket Accept(sockaddr_in& sa, pRecvMsgProc proc);
SOCKET Handle() { return m_hSocket; }
int Recv(void* pBuf, int nLen) { return recv(m_hSocket, (char*)pBuf, nLen, 0); }
int Send(void* pBuf, int nLen) { return send(m_hSocket, (const char*)pBuf, nLen, 0); }
BOOL GetPeerName(sockaddr_in& sa);
BOOL GetSockName(sockaddr_in& sa);
static int GetLastError();
protected:
void InitSockAddr(sockaddr_in& sa,
int sockFamily = AF_INET, LPCTSTR strIP = nullptr, UINT* pPort = nullptr);
BOOL Bind(sockaddr_in& sa) { return !bind(m_hSocket, (const sockaddr*)&sa, sizeof(sa)); }
private:
SOCKET m_hSocket;
};
// .cpp
#define _WINSOCK_DEPRECATED_NO_WARNINGS
#include <process.h>
#include "MySocket.h"
#pragma comment(lib, "ws2_32.lib")
CMySocket::CMySocket(SOCKET sock)
: m_hSocket(sock)
{
WSADATA wd;
if (!WSAStartup(MAKEWORD(2, 15), &wd))
return;
}
CMySocket::~CMySocket()
{
if(m_hSocket == INVALID_SOCKET)
closesocket(m_hSocket);
}
BOOL CMySocket::Create(int nSockFamily, int nSockType, int nProtocol, LPCTSTR strIP, UINT* pPort)
{
SOCKET sock = socket(nSockFamily, nSockType, nProtocol);
if (sock == INVALID_SOCKET) return FALSE;
m_hSocket = sock;
sockaddr_in sa;
InitSockAddr(sa, nSockFamily, strIP, pPort);
if (!Bind(sa)) return FALSE;
return TRUE;
}
void CMySocket::InitSockAddr(sockaddr_in& sa, int sockFamily, LPCTSTR strIP, UINT* pPort)
{
memset((void*)&sa, 0, sizeof(sa));
sa.sin_family = sockFamily; // 协议族
(strIP == nullptr || strIP == "") ?
// ip字符串指针为空或者为空串,ip被初始化为0.0.0.0
sa.sin_addr.S_un.S_addr = htonl(ADDR_ANY) :
// 非空
sa.sin_addr.S_un.S_addr = inet_addr(strIP); // IP
pPort == nullptr ?
// 端口指针为空 端口被初始化为0(系统随机分配空闲端口)
sa.sin_port = htons(0) :
sa.sin_port = htons(*pPort); // port
}
BOOL CMySocket::Connect(LPCTSTR lpszHostAddress, UINT nHostPort)
{
sockaddr_in sa;
InitSockAddr(sa, AF_INET, lpszHostAddress, &nHostPort);
return !connect(m_hSocket, (const sockaddr*)&sa, sizeof(sa));
}
CMySocket CMySocket::Accept(sockaddr_in& sa, pRecvMsgProc proc)
{
int nSize = sizeof(sa);
SOCKET sock = INVALID_SOCKET;
while (TRUE)
{
sock = accept(m_hSocket, (sockaddr*)&sa, &nSize);
if (sock == INVALID_SOCKET) break;
_beginthread(proc, 0, new CMySocket(sock));
}
return CMySocket(sock);
}
BOOL CMySocket::GetPeerName(sockaddr_in& sa)
{
int nSize = sizeof(sa);
return !getpeername(m_hSocket, (sockaddr*)&sa, &nSize);
}
BOOL CMySocket::GetSockName(sockaddr_in& sa)
{
int nSize = sizeof(sa);
return !getsockname(m_hSocket, (sockaddr*)&sa, &nSize);
}
int CMySocket::GetLastError()
{
return WSAGetLastError();
}
// main.cpp
#define _WINSOCK_DEPRECATED_NO_WARNINGS
#include "MySocket.h"
#include <process.h>
#include <iostream>
using namespace std;
void RecvMsgProc(void* pParam)
{
CMySocket* pSock = (CMySocket*)pParam;
char buf[256];
sockaddr_in sa;
int nSize = sizeof(sa);
while (true)
{
int nRet = pSock->Recv((void*)buf, 256);
if (nRet <= 0 || nRet >= 256)
break;
if(!pSock->GetPeerName(sa))
cout << "获取远程主机的IP地址或端口失败" << endl;
else
{
buf[nRet] = '\0';
std::cout << "客户端IP - " << inet_ntoa(sa.sin_addr) << " 端口 - " << htons(sa.sin_port)
<< " 说: " << buf << std::endl;
}
}
pSock = nullptr;
delete pParam;
}
int main()
{
UINT nPort = 33921;
CMySocket sock;
if (!sock.Create(AF_INET, SOCK_STREAM, 0, nullptr, &nPort))
return -1;
if (!sock.Listen()) return FALSE;
cout << "服务启动,运行中..." << endl;
sockaddr_in sa;
if (!sock.GetSockName(sa))
return -1;
cout << "本地服务器IP: " << inet_ntoa(sa.sin_addr) << " 端口: " << htons(sa.sin_port) << endl;
cout << "IP 为 0.0.0.0 表示本地服务器的所有IP都可以接收远程连接,"
<< "端口被指定成唯一的端口号 表示客户端主动连接服务器必然需要一个明确且唯一的端口号。"
<< "服务器提供的网络服务必须要在唯一指定的服务端口上执行" << endl;
CMySocket connectSock = sock.Accept(sa, RecvMsgProc);
if (connectSock.Handle() != SOCKET_ERROR)
_beginthread(RecvMsgProc, 0, new CMySocket(connectSock));
return 0;
}
// client
#pragma once
#include <WinSock2.h>
typedef void(*pRecvMsgProc)(void* pParam);
class CMySocket
{
public:
CMySocket(SOCKET sock = INVALID_SOCKET);
~CMySocket();
BOOL Create(int nSockFamily = AF_INET, int nSockType = SOCK_STREAM, int nProtocol = 0,
LPCTSTR strIP = nullptr, UINT* pPort = nullptr);
BOOL Listen(int backlog = SOMAXCONN) { return !listen(m_hSocket, backlog); }
BOOL Connect(LPCTSTR lpszHostAddress, UINT nHostPort);
CMySocket Accept(sockaddr_in& sa, pRecvMsgProc proc);
SOCKET Handle() { return m_hSocket; }
int Recv(void* pBuf, int nLen) { return recv(m_hSocket, (char*)pBuf, nLen, 0); }
int Send(void* pBuf, int nLen) { return send(m_hSocket, (const char*)pBuf, nLen, 0); }
BOOL GetPeerName(sockaddr_in& sa);
BOOL GetSockName(sockaddr_in& sa);
static int GetLastError();
protected:
void InitSockAddr(sockaddr_in& sa,
int sockFamily = AF_INET, LPCTSTR strIP = nullptr, UINT* pPort = nullptr);
BOOL Bind(sockaddr_in& sa) { return !bind(m_hSocket, (const sockaddr*)&sa, sizeof(sa)); }
private:
SOCKET m_hSocket;
};
#define _WINSOCK_DEPRECATED_NO_WARNINGS
#include <process.h>
#include "MySocket.h"
#pragma comment(lib, "ws2_32.lib")
CMySocket::CMySocket(SOCKET sock)
: m_hSocket(sock)
{
WSADATA wd;
if (!WSAStartup(MAKEWORD(2, 15), &wd))
return;
}
CMySocket::~CMySocket()
{
if(m_hSocket == INVALID_SOCKET)
closesocket(m_hSocket);
}
BOOL CMySocket::Create(int nSockFamily, int nSockType, int nProtocol, LPCTSTR strIP, UINT* pPort)
{
SOCKET sock = socket(nSockFamily, nSockType, nProtocol);
if (sock == INVALID_SOCKET) return FALSE;
m_hSocket = sock;
sockaddr_in sa;
InitSockAddr(sa, nSockFamily, strIP, pPort);
if (!Bind(sa)) return FALSE;
return TRUE;
}
void CMySocket::InitSockAddr(sockaddr_in& sa, int sockFamily, LPCTSTR strIP, UINT* pPort)
{
memset((void*)&sa, 0, sizeof(sa));
sa.sin_family = sockFamily; // 协议族
(strIP == nullptr || strIP == "") ?
// ip字符串指针为空或者为空串,ip被初始化为0.0.0.0
sa.sin_addr.S_un.S_addr = htonl(ADDR_ANY) :
// 非空
sa.sin_addr.S_un.S_addr = inet_addr(strIP); // IP
pPort == nullptr ?
// 端口指针为空 端口被初始化为0(系统随机分配空闲端口)
sa.sin_port = htons(0) :
sa.sin_port = htons(*pPort); // port
}
BOOL CMySocket::Connect(LPCTSTR lpszHostAddress, UINT nHostPort)
{
sockaddr_in sa;
InitSockAddr(sa, AF_INET, lpszHostAddress, &nHostPort);
return !connect(m_hSocket, (const sockaddr*)&sa, sizeof(sa));
}
CMySocket CMySocket::Accept(sockaddr_in& sa, pRecvMsgProc proc)
{
int nSize = sizeof(sa);
SOCKET sock = INVALID_SOCKET;
while (TRUE)
{
sock = accept(m_hSocket, (sockaddr*)&sa, &nSize);
if (sock == INVALID_SOCKET) break;
_beginthread(proc, 0, new CMySocket(sock));
}
return CMySocket(sock);
}
BOOL CMySocket::GetPeerName(sockaddr_in& sa)
{
int nSize = sizeof(sa);
return !getpeername(m_hSocket, (sockaddr*)&sa, &nSize);
}
BOOL CMySocket::GetSockName(sockaddr_in& sa)
{
int nSize = sizeof(sa);
return !getsockname(m_hSocket, (sockaddr*)&sa, &nSize);
}
int CMySocket::GetLastError()
{
return WSAGetLastError();
}
#define _WINSOCK_DEPRECATED_NO_WARNINGS
#include "MySocket.h"
#include <iostream>
#include <process.h>
using namespace std;
const int nServicePort = 33921;
const char* pStrServiceIP = "192.168.0.233";
void RecvMsgProc(void* pParam)
{
CMySocket* pSock = (CMySocket*)pParam;
char buf[256];
sockaddr_in sa;
int nSize = sizeof(sa);
while (true)
{
int nRet = pSock->Recv((void*)buf, 256);
if (nRet <= 0 || nRet >= 256)
break;
if (!pSock->GetPeerName(sa))
cout << "获取远程主机的IP地址或端口失败" << endl;
else
{
buf[nRet] = '\0';
std::cout << "客户端IP - " << inet_ntoa(sa.sin_addr) << " 端口 - " << htons(sa.sin_port)
<< " 说: " << buf << std::endl;
}
}
pSock = nullptr;
delete pParam;
}
int main()
{
CMySocket sock;
if (!sock.Create())
return -1;
if (!sock.Connect(pStrServiceIP, nServicePort))
return -1;
sockaddr_in sa;
if (!sock.GetPeerName(sa)) // 建立稳定连接后才可以获取对端的IP和端口
return -1;
cout << "服务器IP: " << inet_ntoa(sa.sin_addr) << " 端口: " << htons(sa.sin_port) << endl;
if (!sock.GetSockName(sa)) // 只要监听开始就可以获取自己的IP和端口
return -1;
cout << "本地的IP: " << inet_ntoa(sa.sin_addr) << " 端口: " << htons(sa.sin_port) << endl;
char s[256];
while (true)
{
cin >> s;
sock.Send(s, strlen(s));
}
return 0;
}
epoll asio boost muduo了解下?
不了解