#include "stdafx.h" #include #include #include #ifndef _WINSOCKAPI_ #include #endif #if _MSC_VER > 1000 #pragma once #endif // _MSC_VER > 1000 #define WINSOCK_VERSION_REQUIRED 0x0101 #define WINSOCK_MIN_SOCKETS_REQUIRED 1 #define PDELETE(p) {if(p) delete p;p=NULL;} BOOL initDll(WSADATA* pwsaData); BOOL ShowIPAddress(); void WriteFormat(unsigned char* buf, int nRecvLen); void thTCPListen(LPVOID pvParams); void thUDPListen(LPVOID pvParams); static void GetRemoteHost( sockaddr_in* psa, char* szString, int nBuflen ); // global variable int bKeepAlive = 1; // ------------------------------------------------------------------ // main // ------------------------------------------------------------------ int main(int argc, char* argv[]) { char szRemoteHost[256]; // localdata sockaddr_in local; // client data sockaddr_in saFrom; int nFromLen = sizeof(sockaddr_in); SOCKET sClient; // -------------------------------------------------------------- // Init Socket // -------------------------------------------------------------- WSADATA wsaData; if( !initDll(&wsaData) ) { printf("WSAStartup failed."); return 0; } printf("// ---------------------------------------------------------------------------\n"); printf("TCP UDP Echo server\n"); printf("Description\t:%s\n",wsaData.szDescription); printf("Systemstatus\t:%s\n",wsaData.szSystemStatus); printf("http://www001.upp.so-net.ne.jp/ishi/index.html\n"); printf("// ---------------------------------------------------------------------------\n"); printf("This server listen both UDP and TCP\n"); // -------------------------------------------------------------- // Determine Port no. // -------------------------------------------------------------- unsigned int nPort = 0; char work[32]; printf("Listen port?(default 7): "); gets(work); work[32] = '\0'; nPort = atoi(work); if( nPort == 0 ) nPort = 7; printf( "waiting at %d port.\n", nPort); printf("TCP echo need KeepAlive?(y/n): "); gets(work); bKeepAlive = ( *work == 'y' || *work == 'Y' ); if( bKeepAlive ) puts("KeepAlive on"); else puts("KeepAlive off"); if( !ShowIPAddress() ) return 0; // -------------------------------------------------------------- // Create UDP server // -------------------------------------------------------------- _beginthread( thUDPListen, 1024, &nPort ); // -------------------------------------------------------------- // Create TCP server // -------------------------------------------------------------- local.sin_family = AF_INET; // TCP/IP local.sin_addr.s_addr = INADDR_ANY; // all NIC card local.sin_port = htons(nPort); // Port no SOCKET s; s = socket(AF_INET, SOCK_STREAM, 0); if (s == INVALID_SOCKET) return -1; // -------------------------------------------------------------- // bind // -------------------------------------------------------------- if (::bind(s,(struct sockaddr*)&local,sizeof(local) ) == SOCKET_ERROR) { printf( "bind error.\n" ); return -1; } // -------------------------------------------------------------- // listen // -------------------------------------------------------------- if (::listen(s,SOMAXCONN) == SOCKET_ERROR) { printf( "listen error.\n" ); return -1; } // -------------------------------------------------------------- // Accept // -------------------------------------------------------------- while(1) { sClient = ::accept(s, (sockaddr*)&saFrom, &nFromLen); if( sClient == INVALID_SOCKET ) { printf( "accept failed.\nThread is going down.\n" ); } GetRemoteHost( (sockaddr_in*)&saFrom, szRemoteHost, 256 ); printf( "** FROM:%s\n", szRemoteHost ); // -------------------------------------------------------------- // Create TCP recv thread // -------------------------------------------------------------- _beginthread(thTCPListen, 1024, &sClient ); } return 0; } // ------------------------------------------------------------------ // winsock Init // ------------------------------------------------------------------ BOOL initDll(WSADATA* pwsaData) { int winsockstartup = WSAStartup(WINSOCK_VERSION_REQUIRED,pwsaData); if (winsockstartup != 0 || pwsaData->iMaxSockets < WINSOCK_MIN_SOCKETS_REQUIRED) { WSACleanup(); return 0; } return TRUE; } // ------------------------------------------------------------------ // Enum IP address // ------------------------------------------------------------------ BOOL ShowIPAddress() { // IPaddress char szHostName[256]; szHostName[0] = '\0'; int nResult = gethostname( szHostName, sizeof( szHostName ) ); if( nResult != 0 || szHostName[0] == '\0' ) { printf( "gethostname() failed. IP address unknown." ); return FALSE; } HOSTENT* lphostent = gethostbyname( szHostName ); if( lphostent == NULL ) { printf( "gethostname() failed. IP address unknown." ); return FALSE; } char** hostaddr = lphostent->h_addr_list; while( *hostaddr != NULL ) { printf("Listen address %d.%d.%d.%d\n", (UCHAR)(*hostaddr)[0], (UCHAR)(*hostaddr)[1], (UCHAR)(*hostaddr)[2], (UCHAR)(*hostaddr)[3] ); hostaddr++; } return TRUE; } // ------------------------------------------------------------------ // GetRemoteHost // ------------------------------------------------------------------ static void GetRemoteHost( sockaddr_in* psa, char* szString, int nBuflen ) { char szWork[256]; memset( szString, 0, nBuflen ); u_char* p = (u_char*)&(psa->sin_addr.S_un.S_un_b); sprintf( szWork, "%u.%u.%u.%u:%d", p[0], p[1], p[2], p[3], psa->sin_port ); strncpy( szString, szWork, nBuflen ); } // ------------------------------------------------------------------ // WriteFormat // ------------------------------------------------------------------ void WriteFormat(unsigned char* buf, int nRecvLen) { int xx; unsigned char* str = buf; int nLen = nRecvLen; do { // ---------------------------------------------------------- // Dump binary // ---------------------------------------------------------- for(xx = 0, nLen = nRecvLen, str = buf; xx < 20; xx++, nLen--, str++) { if( nLen > 0 ) printf( "%02X ", *str ); else printf( "-- " ); } str = buf; // ---------------------------------------------------------- // Print ascii char // ---------------------------------------------------------- for(xx = 0, nLen = nRecvLen, str = buf; xx < 20; xx++, nLen--, str++) { if( isprint(*str) ) printf("%c", *str); else printf("."); } buf = str; nRecvLen = nLen; } while( nLen > 0 ); printf( "\n" ); } // ------------------------------------------------------------------ // TCP thread // ------------------------------------------------------------------ void thTCPListen(LPVOID pvParams) { printf("Thread is up.\n"); SOCKET Soc = *(SOCKET*)pvParams; int nReadLen = 0; unsigned char buf[4096]; do { memset( buf, 0, 4096 ); nReadLen = recv( Soc, (char*)buf, 4096, 0 ); WriteFormat( buf, nReadLen ); ::send( Soc, (char*)buf, nReadLen, 0 ); }while( nReadLen > 0 && bKeepAlive ); ::closesocket(Soc); printf("Thread is down.\n"); _endthread(); } // ------------------------------------------------------------------ // UDP thread // ------------------------------------------------------------------ void thUDPListen(LPVOID pvParams) { char szRemoteHost[256]; u_short nPort = *(u_short*)pvParams; int nReadLen = 0; unsigned char buf[4096]; int result = 0; // localdata sockaddr_in local; // client data sockaddr_in saFrom; int nFromLen = sizeof(sockaddr_in); // -------------------------------------------------------------- // Create server // -------------------------------------------------------------- local.sin_family = AF_INET; // TCP/IP local.sin_addr.s_addr = INADDR_ANY; // All NIC card local.sin_port = htons(nPort); // Port SOCKET s; s = socket(AF_INET, SOCK_DGRAM, 0); if (s == INVALID_SOCKET) { printf( "UDP: socket() error." ); return; } // -------------------------------------------------------------- // bind // -------------------------------------------------------------- if (::bind(s,(struct sockaddr*)&local,sizeof(local) ) == SOCKET_ERROR) { printf( "UDP: bind() error.\n" ); return ; } while(1) { result = recvfrom( s, (char*)buf, sizeof(buf), 0, (sockaddr*)&saFrom, &nFromLen ); GetRemoteHost( (sockaddr_in*)&saFrom, szRemoteHost, 256 ); printf( "** RECV:%d FROM:%s\n", result, szRemoteHost ); if(result>0) { WriteFormat(buf, result); } sendto( s, (char*)buf, result, 0, (sockaddr*)&saFrom, nFromLen ); } _endthread(); }