📄 tcpsocket.cpp
字号:
// TcpSocket.cpp: implementation of the CTcpSocket class.
//
//////////////////////////////////////////////////////////////////////
#include "stdafx.h"
#include "TcpSocket.h"
#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif
#define TCP_BUFFER_LENGTH 512
#define TCP_DATA_QUEUE_SIZE 128
LPWSAPROTOCOL_INFO CTcpSocket::m_pProtocolsInfo;
LPWSAPROTOCOL_INFO CTcpSocket::m_pTcpInfo;
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
CTcpSocket::CTcpSocket()
{
m_socket = INVALID_SOCKET;
m_hIOThread = NULL;
m_hNetEvent = m_hOutputEvent = m_hQuitEvent = NULL;
m_bWriteOk = FALSE;
m_bPDA = FALSE;
m_bPDA_Audio = FALSE;
OutputDebugString("no error!");
}
CTcpSocket::~CTcpSocket()
{
if (m_socket != INVALID_SOCKET)
Unprepare();
}
//////////////////////////////////////////////////////////////////////
// CTcpSocket public functions
void CTcpSocket::SetPDA()
{
m_bPDA = TRUE;
}
void CTcpSocket::SetPDAAudio()
{
m_bPDA_Audio = TRUE;
}
BOOL CTcpSocket::Call(ULONG uPeerIP, HWND hWnd, int iPort)
{
SOCKADDR_IN addr;
int err;
m_hWnd = hWnd;
m_iPort = (iPort == 0) ? TCP_DEFAULT_PORT : iPort;
if (Prepare() == FALSE)
return FALSE;
// Create a socket for this connection.
m_socket = WSASocket(FROM_PROTOCOL_INFO, FROM_PROTOCOL_INFO, FROM_PROTOCOL_INFO, m_pTcpInfo, 0, 0);
if (m_socket == INVALID_SOCKET)
{
OutputDebugString("Could not open a socket in Call\n");
goto Error;
}
else
{ // Set up socket for windows message event notification.
int ppp=WSAAsyncSelect(m_socket, m_hWnd, WM_TCP_SOCKET_CONNECT, FD_CONNECT);
int pp=WSAGetLastError();
}
addr.sin_family = AF_INET;
addr.sin_port = htons(m_iPort);
addr.sin_addr.s_addr = uPeerIP;
err = WSAConnect(m_socket, (SOCKADDR *)&addr, m_pTcpInfo->iMaxSockAddr, NULL, NULL, NULL, NULL);
if (err == SOCKET_ERROR)
{
err = WSAGetLastError();
if (err != WSAEWOULDBLOCK)
{
OutputDebugString("WSAConnect failed\n");
goto Error;
}
}
else
{
OutputDebugString("WSAConnect should have returned SOCKET_ERROR\n");
goto Error;
}
m_uPeerIP = addr.sin_addr.s_addr;
m_strPeerName = inet_ntoa(addr.sin_addr);
OutputDebugString("Calling " + m_strPeerName + "\n");
return TRUE;
Error:
Unprepare();
return FALSE;
}
void CTcpSocket::Hangup()
{
if (m_hQuitEvent != NULL) SetEvent(m_hQuitEvent);
}
BOOL CTcpSocket::Write(char * pData, int iLength)
{
if (m_hOutputEvent == NULL) return FALSE;
CSingleLock sLock(&m_critical);
WSABUF * p = (WSABUF *)malloc(sizeof(WSABUF));
if (p == NULL)
{
OutputDebugString("malloc failed in CTcpSocket::Write\n");
return FALSE;
}
p->buf = (char *)malloc(TCP_BUFFER_LENGTH);
if (p->buf == NULL)
{
free(p);
OutputDebugString("malloc failed in CTcpSocket::Write\n");
return FALSE;
}
memcpy(p->buf, pData, iLength);
p->len = iLength;
sLock.Lock();
m_sendQueue.AddTail(p);
sLock.Unlock();
SetEvent(m_hOutputEvent);
// Sleep(0);
return TRUE;
}
ULONG CTcpSocket::Accept(SOCKET socketListen, LPARAM lParam, HWND hWnd, int iPort)
{
SOCKADDR_IN addr;
int iAddrLen = sizeof(addr);
int err;
DWORD dwThreadId; // needed for CreateThread
err = WSAGETSELECTERROR(lParam);
// Check to see if there was an error on the connection attempt.
if (err)
{ // Some kind of error occurred.
if (err == WSAENETDOWN)
{
OutputDebugString("The network is down\n");
}
else
{
OutputDebugString("Unknown error on FD_ACCEPT\n");
}
return 0;
}
m_hWnd = hWnd;
//modified by zhb
m_iPort = (iPort == 0) ? TCP_DEFAULT_PORT : iPort;
//
if (Prepare() == FALSE) return 0;
m_socket = WSAAccept(socketListen, (SOCKADDR *)&addr, &iAddrLen, NULL, (DWORD)NULL);
if (m_socket == INVALID_SOCKET)
{
err = WSAGetLastError();
if (err != WSAECONNREFUSED)
{
OutputDebugString("WSAAccept failed\n");
goto Error;
}
else
{
OutputDebugString("The connection attempt has been refused\n");
goto Error;
}
}
m_uPeerIP = addr.sin_addr.s_addr;
m_iPeerPort =addr.sin_port;
m_strPeerName = inet_ntoa(addr.sin_addr);
WSAAsyncSelect(m_socket, m_hWnd, 0, 0);
// Put Connection in Event Object Notification Mode.
WSAEventSelect(m_socket, m_hNetEvent, FD_READ | FD_WRITE | FD_CLOSE);
// Start the I/O thread, and save the thread handle.
m_hIOThread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)ThreadFunc, this, 0, &dwThreadId);
if (m_hIOThread == NULL)
{
OutputDebugString("CreateThread() failed in HandleAcceptMessage()\n");
goto Error;
}
OutputDebugString(m_strPeerName + " joined the meeting\n");
return m_uPeerIP;
Error:
Unprepare();
return 0;
}
ULONG CTcpSocket::OnConnect(LPARAM lParam)
{
int err;
DWORD dwThreadId; // needed for CreateThread
err = WSAGETSELECTERROR(lParam);
// Check to see if there was an error on the connection attempt.
if (err)
{
// Some kind of error occurred.
if (err == WSAECONNREFUSED)
{
OutputDebugString(m_strPeerName + " 处没有应用程序应答\n");
}
else
{
OutputDebugString(m_strPeerName + " 没有在网络上\n");
}
goto Error;
}
WSAAsyncSelect(m_socket, m_hWnd, 0, 0);
// Put Connection in Event Object Notification Mode.
WSAEventSelect(m_socket, m_hNetEvent, FD_READ | FD_WRITE | FD_CLOSE);
// Start the I/O thread, and save the thread handle.
m_hIOThread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)ThreadFunc, this, 0, &dwThreadId);
if (m_hIOThread == NULL)
{
OutputDebugString("CreateThread() failed in OnConnect()\n");
goto Error;
}
OutputDebugString(m_strPeerName + " joined the meeting\n");
return m_uPeerIP;
Error:
Unprepare();
return 0;
}
void CTcpSocket::OnClose()
{
Unprepare();
}
//////////////////////////////////////////////////////////////////////
// CTcpSocket protected functions
BOOL CTcpSocket::Prepare()
{
m_hNetEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
m_hOutputEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
m_hQuitEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
if (!m_hNetEvent || !m_hOutputEvent || !m_hQuitEvent)
{
OutputDebugString("CreateEvent fail in Prepare connection data\n");
goto Error;
}
m_eventArray[0] = m_hNetEvent;
m_eventArray[1] = m_hOutputEvent;
m_eventArray[2] = m_hQuitEvent;
return TRUE;
Error:
Unprepare();
return FALSE;
}
void CTcpSocket::Unprepare()
{
if (m_hNetEvent != NULL)
{
CloseHandle(m_hNetEvent);
m_hNetEvent = NULL;
}
if (m_hOutputEvent != NULL)
{
CloseHandle(m_hOutputEvent);
m_hOutputEvent = NULL;
}
if (m_hQuitEvent != NULL)
{
CloseHandle(m_hQuitEvent);
m_hQuitEvent = NULL;
}
if (m_hIOThread != NULL)
{
CloseHandle(m_hIOThread);
m_hIOThread = NULL;
}
while (!m_sendQueue.IsEmpty())
{
WSABUF * p = m_sendQueue.RemoveHead();
free(p->buf);
free(p);
}
if (m_socket != INVALID_SOCKET)
{
WSAEventSelect(m_socket, m_hNetEvent, 0);
closesocket(m_socket);
m_socket = INVALID_SOCKET;
}
}
//////////////////////////////////////////////////////////////////////
// CTcpSocket Static functions
BOOL CTcpSocket::Startup()
{
int i, err;
DWORD dwBufferSize = 0; // size of m_pProtocolsInfo buffer
WORD wVersionRequested;
BOOL bFoundTcp = FALSE;
WSADATA wsaData;
m_pProtocolsInfo = NULL;
// Asynchronous IO and multicast semantics we use supported starting only with WinSock 2.0
wVersionRequested = MAKEWORD (2, 2);
// Start WinSock 2. If it fails, we don't need to call WSACleanup().
err = WSAStartup (wVersionRequested, &wsaData);
if (err != 0)
{
OutputDebugString("Could not find high enough version of WinSock\n");
return FALSE;
}
if (LOBYTE(wsaData.wVersion) != 2 || HIBYTE(wsaData.wVersion) !=2 )
{
OutputDebugString("Could not find the correct version of WinSock\n");
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -