////////////////////////////////////////////////////////////////////////// // Lan protocol #include "stdafx.h" #include "lan.h" CLan::CLan() { m_income = INVALID_SOCKET; m_filesoc = INVALID_SOCKET; m_status = LS_OK; m_mode = LM_OFF; m_hListenThread = NULL; m_hAcceptTCPThread = NULL; InitializeCriticalSection(&m_csAcceptTCPThread); Startup(); } CLan::~CLan() { Shutdown(); DeleteCriticalSection(&m_csAcceptTCPThread); } void CLan::Startup() { WSADATA wsa; if (WSAStartup(MAKEWORD(2,2), &wsa)==0) { m_status = LS_OK; m_mode = LM_ON; char hostname[256]; if (gethostname(hostname, 256)==0) { hostent* host = gethostbyname(hostname); char** pAddr = host->h_addr_list; m_hostAddrCount = 0; while (*pAddr && m_hostAddrCountListen(); return 0; } void CLan::Listen() { if (m_mode==LM_LISTEN) { char buf[65536]; while(1) { sockaddr_in addr; int addrLen = sizeof(addr); Sleep(20); int recLen = recvfrom(m_income, buf, 65536, 0, (sockaddr*)&addr, &addrLen); if (recLen!=SOCKET_ERROR) OnRecvPacket((u_char*)buf, recLen, addr.sin_addr); } } } void CLan::SendPacketBroadcast(const u_char* mes, int len) { in_addr addr; addr.S_un.S_addr = INADDR_BROADCAST; SendPacket(addr, mes, len); } void CLan::SendPacket(in_addr addr, const u_char* mes, int len) { if (m_mode==LM_LISTEN) { sockaddr_in addrTo; addrTo.sin_addr = addr; addrTo.sin_family = AF_INET; addrTo.sin_port = PORT_NUMBER; int res = sendto(m_income, (const char*)mes, len, 0, (sockaddr*)&addrTo, sizeof(addrTo)); } } ////////////////////////////////////////////////////////////////////////// DWORD WINAPI CLan::AcceptTCPProc(LPVOID lpParameter) { CLan* lan = (CLan*)lpParameter; lan->AcceptTCP(); return 0; } void CLan::AcceptTCP() { while (1) { SOCKET in_socket; sockaddr_in addrFrom; int addrLen = sizeof(addrFrom); in_socket = accept(m_filesoc, (sockaddr*)&addrFrom, &addrLen); EnterCriticalSection(&m_csAcceptTCPThread); if (in_socket != INVALID_SOCKET) { TTCPConnect* tcp_conn = new TTCPConnect; tcp_conn->m_addr = addrFrom.sin_addr.S_un.S_addr; tcp_conn->m_lan = this; tcp_conn->m_socket = in_socket; DWORD threadId; CreateThread(NULL, 0, OnInTCPConnectionProc, (LPVOID)tcp_conn, 0, &threadId); } LeaveCriticalSection(&m_csAcceptTCPThread); Sleep(100); } } DWORD WINAPI CLan::OnInTCPConnectionProc(LPVOID lpParameter) { TTCPConnect* tcp_conn = (TTCPConnect*)lpParameter; tcp_conn->m_lan->OnInTCPConnection(tcp_conn->m_addr, tcp_conn->m_socket); shutdown(tcp_conn->m_socket, SD_BOTH); closesocket(tcp_conn->m_socket); delete tcp_conn; return 0; } SOCKET CLan::CreateTCPConnection(u_long addr, LPVOID lpParameter) { SOCKET out_socket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); if (out_socket==INVALID_SOCKET) return INVALID_SOCKET; sockaddr_in addrTo; addrTo.sin_addr.S_un.S_addr = addr; addrTo.sin_family = AF_INET; addrTo.sin_port = PORT_NUMBER; if (connect(out_socket, (sockaddr*)&addrTo, sizeof(addrTo))!=0) { closesocket(out_socket); out_socket = INVALID_SOCKET; } //OnOutTCPConnectionProc is called anyway TTCPConnect* tcp_conn = new TTCPConnect; tcp_conn->m_socket = out_socket; tcp_conn->m_lan = this; tcp_conn->m_addr = addr; tcp_conn->m_lpParameter = lpParameter; DWORD threadId; CreateThread(NULL, 0, OnOutTCPConnectionProc, (LPVOID)tcp_conn, 0, &threadId); return out_socket; } DWORD WINAPI CLan::OnOutTCPConnectionProc(LPVOID lpParameter) { TTCPConnect* tcp_conn = (TTCPConnect*)lpParameter; tcp_conn->m_lan->OnOutTCPConnection(tcp_conn->m_addr, tcp_conn->m_socket, tcp_conn->m_lpParameter); shutdown(tcp_conn->m_socket, SD_BOTH); closesocket(tcp_conn->m_socket); delete tcp_conn; return 0; }