// TCP.H: Basic Network Communication Package ////
#ifndef __tcp_h __ # define __tcp_h__
#include
#define WM_TCP WM_APP 100
Class CTCP {public: CTCP (); ~ CTCP ();
// extern int SD_CONNECT, SD_BIND, SD_ACCEPT; int WSA_OK; static void peek_message (void); static int GET_LOCAL_IP (CHAR * IP); int init (); int exit ();
INT BIND_LISTEN (Int Port, SockAddr_in & Addr, Long & Err); INT Status (int SD, Char * Type, INT TIMEOUT = 5); int bind (hwnd hwnd, int port); int bind2 (hwnd hwnd, char * ip, int port); int accept (int sd, int timeout); int connect (char * hostname, int port, int timeout, int f_noblock); int connect2 (char * bind_ip, char * hostname, int port, int timeout, int f_noblock) ; Void Disconnect (int SD); Void Close (INT & SD);
INT Send (int SD, Char * BUF, INT LEN, INT TIMEOUT = 10); int RECV (int SD, Char * BUF, INT LEN, INT TIMEOUT = 10); int gethostnamebyip (char * ip, char * name); unsigned short htons (unsigned short); unsigned short ntohs (unsigned short); unsigned long int htonl (unsigned long int); unsigned long int ntohl (unsigned long int); unsigned __int64 ntohh (unsigned __int64); unsigned __int64 htonh (unsigned __int64 ); Float htonf (float f); float ntohf (float f); double htond (double d); char * get_remote_ip (int SD, char * ip);
#ENDIF
-------------------------------------------------- ---- // TCP.cpp: Implementation of the ctcp class.////
#include "stdafx.h" #include
#include "tcp.h"
Extern writelog (char * file_name, char * format, ...); extern writeestat (char * format, ...);
/ / / CONSTRUCTION / DESTRUCTION // CTCP :: CTCP () {WSA_OK = 0;}
CTCP :: ~ ctcp () {
}
INT ctcp :: init () {if (! wsa_ok) {Wsadata WSA;
// sd_bind = SD_CONNECT = SD_ACCEPT = -1; IF (WsaStartup (MakeWord (1, 1), & WSA)! = 0) Return -1; WSA_OK = 1;} return 0;}
INT ctcp :: exit () {if (wsa_ok) wsacleanup ();
Return 0;}
INT CTCP :: Status (int SD, Char * TYPE, INT TIMEOUT) {FD_SET RSET, WSET, ESET; FD_SET FAR * PRSET = NULL, * PWSET = NULL, * PESET = NULL; Struct Timeval TVal; Int i, status, Err_no = 0; TIME_T T1, T2; MSG MSG;
TVAL.TV_SEC = 0; tval.tv_usec = 1; TIME (& T1); T2 = T1; While (T2-T1 For (i = 0; I <(int) strlen (type); i ) {IF (Type [i] == 'r') {fd_set (sd, & rset); prSet = & rset;} if (Type [i] == 'W') {fd_set (sd, & wset); pwset = & wset;} if (Type [i] == 'e') {fd_set (sd, & eset); peset = & eset;}} status = SELECT 1, PRSET, PWSET, PESET, & TVAL); err_no = wsagetlasterror (); int err = getLastError (); // Writestat ("SELECT Err_NO =% D, Err =% D", err_no, err); TIME (& T2) ; If (status == 0) {IF (PEEKMESSAG, NULL, NULL, PM_REMOVE)) {TranslateMessage (& MSG); DispatchMessage (& MSG); if (msg.Message == WM_QUIT) {// Wsasetlasterror (WSaetimeout ); Return -1;}}} (t2-t1 IF (Pset && fd_isset (SD, PESET)) {if (PRSET! = NULL) FD_CLR ((UINT) SD, & RSET); if (PWSET! = NULL) FD_CLR ((UINT) SD, & WSET); if (Pset! = NULL) FD_CLR ((uint) SD, & Eset); // err_no = wsagetlasterror (); / * len = sizeof (errno); GetSockopt (SD, SOL_Socket, SO_ERROR, (CHAR *) & errno, & len); * / wsasetlasterror (Err_no); Return -1;} IF ((PRSET && fd_isset (sd, prset)) || (PWSET && FD_ISSET (SD, PWSET))) {// err_no = wsagetlasterror (); / * len = sizeof (errno ); GetSockopt (SD, SOL_SOCKET, SO_ERROR, (CHAR *) & errno, & len; * /} if (prSt! = NULL) FD_CLR ((UINT) SD, & RSET); if (Pwset! = NULL) FD_CLR ((UINT) SD, & WSET; if (peset! = null) FD_CLR ((uint) SD, & ESET); // if (status <0) // err_no = wsagetlasterror (); wsasetlasterror (err_no); if (err_no == WSAEINTR) ) {Return WSAEINTR;} f (err_no) {return -1;} else break; Return 0;} INT CTCP :: Bind (hwnd hwnd, int port) {structure sockaddr_in addr; char TEMP [200]; int SD; SD = -1; IF ((SD = Socket, Sock_Stream, Ipproto_TCP)) <0) {Sprintf (Temp, "Socket Failed! Errno:% D", Wsagetlasterror ()); return -1;} MEMSET (& Addr, 0, SizeOf (AddR)); Addr.sin_Family = AF_INET; addr.sin_port = htons (unsigned short); int L = 1; setsockopt (SD, SOL_SOCKET, SO_REUSEADDR, (CHAR *) & L, SizeOf (L)); / * setsockopt (SD, Sol_socket, so_reuseport, (char *) & l, sizeof (l)); * / if (:: bind (SD, STRUCKADDR *) & addr, sizeof (addr) <0) {sprintf (Temp, "Bind Failed! Errno:% D ", wsagetlasterror ()); CloseSocket (SD); Return -1;} if (HWND && WSaasyncselect (SD, HWND, WM_TCP, FD_ACCEPT)! = 0) {Sprintf (Temp," TCP_Bind: WSaasyncselect Failed! "); CloseSocket (SD); RETURN-2;} // sd_bind = SD; Listen (SD, 5); Return SD;} int ctcp :: bind2 (hwnd hwnd, char * ip, int port) {struct sockaddr_in addr CHAR TEMP [200]; int SD; SD = -1; IF ((SD = Socket, Sock_Stream, Ipproto_TCP)) <0) {Sprintf (Temp, "Socket Failed! Errno:% D", Wsagetlasterror ()); return -1;} IF (IP & Addr, 0, SIZEOF (AddR)); ulong ul = inet_addr (ip); if (ul == 0xfffffffff) {CloseSocket (SD); return -1;} else addr.sin_addr .s_addr = ul;} Memset (& addr, 0, sizeof (addr); Addr.sin_Family = AF_INET; addr.sin_port = htons (unsigned short); int L = 1; setsockopt (SD, SOL_SOCKET, SO_REUSEADDR, (CHAR *) & L, SizeOf (L)); / * setsockopt (SD, Sol_socket, so_reuseport, (char *) & l, sizeof (l)); * / if (:: bind (SD, STRUCKADDR *) & addr, sizeof (addr) <0) {sprintf (Temp, "Bind Failed! Errno:% D ", wsagetlasterror ()); CloseSocket (SD); Return -1;} if (HWND && WSaasyncselect (SD, HWND, WM_TCP, FD_ACCEPT)! = 0) {Sprintf (Temp," TCP_Bind: WSaasyncselect Failed! "); CloseSocket (SD); RETURN-2;} // sd_bind = SD; Listen (SD, 5); Return SD;} int CTCP :: Accept (int SD, int Timeout) {int SD_ACC = -1; struct SockAddr_in sa; int LEN; / * unsigned long L; * / IF (STATUS (SD, "RW", TIMEOUT <0) Return -1; Len = SizeOf (SA); IF ((SD_ACC = :: Accept (SD, SD, STRUCKADDR *) & SA, & LEN) <0) Return -1; // sd_accept = SD_ACC; / * L = 1; IF (IOCTLSOCKET (SD_ACC, Fionbio, & L) <0) {CloseSocket (SD); return -1;} * / return SD_ACC;} INT CTCP :: Connect (Char * Hostname, INT Port, INT TIMEOUT, INT F_NOBLOCK) {struct hostent * hp; struct sockaddr_in addr; char Temp [200]; unsigned long ul; long L; int SD = -1, return; TIME_T T1, T2; SD = -1; IF ((SD = :: SOCKET (AF_INET, SOCK_STREAM, IPPROTO_TCP) <0) {Sprintf (Temp, "Socket Failed! Errno:% D", wsagetlasterror ()); Return -1;} MEMSET (& Addr, 0, SizeOf (AddR)); UL = inet_addr (HostName); if (ul == 0xfffffffff) {IF ((HP = gethostByname (HostName)) == null) {sprintf (Temp, "gethostByname and inet_addr failed! errno:% D", wsagetlasterror ()) CloseSocket (SD); RETURN-1;} Memcpy (& addr.sin_addr, hp-> h_addr, hp-> h_length);} else addr.sin_addr.s_addr = ul; addr.sin_family = AF_INET; addr.sin_port = htons (unsigned short); l = 1; if (/ * f_noblock && * / ioctlsocket (SD, Fionbio, (unsigned long *) & l) <0) {CloseSocket (SD); return -1;} / * if Setsockopt (SD, IPPROTO_TCP, TCP_NODELAY, (CHAR *) & L, SIZEOF (L)) <0) {CloseSocket (SD); Return -1;} * / Time (& T1); int counter = 0; while ((Ret = :: Connect (SD, STRUCKADDR *) & addr, sizeof (addr)))))! = 0) {TIME (& T2); if ((t2 -t1)> timeout) {CloseSocket (SD); return -1;} PEEK_MESSAGE (); int err_no = wsagetlasterror (); if (ret == socket_error) {if (counter > 10) {Sleep (100); counter = 0 } If (err_no == wsaeisconn) Break;} else if (err_no == wsaewouldblock / * || err_no == wsaeinprogress * / || err_no == wsaealready) {Continue;} else {CloseSocket (SD); Return -1 ;}}} (STATUS (SD, "WE", TIMEOUT <0) {sprintf (Temp, "status: ¬¬¬ ó · þþññ ÷ ÷ § ° ü! ///10ì2é · þþñæ ÷ 3ìðòêç · ñ ðððð / nçòö ÷» úμØö ç · ñ% s ë¿ Úêç · ñ% d / n "" errno =% d ", hostname, port, wsagetlasterror ()); CloseSocket (SD); return -1;} // SD_CONNECT = SD; RETURN SD;} INT CTCP :: Connect2 (Char * Bind_IP, Char * Hostname, INT Port, INT TIMEOUT, INT F_NOBLOCK) {struct hostent * hp; struct sockaddr_in addr; char Temp [200]; unsigned long UL; long L; int SD = 1, RET; TIME_T T1, T2; SD = -1; IF ((SD = Socket, Sock_Stream, Ipproto_TCP)) <0) {Sprintf (Temp, "Socket Failed! Errno:% D", WsageTlasterror ()) Return -1;} IF (bind_ip&& * bind_ip) {MEMSET (& addr, 0, sizeof (addr)); addr.sin_family = AF_INET; ul = inet_addr (bind_ip); if (ul == 0xfffffffff) {CloseSocket (SD); Return -1; } Else addr.sin_addr.s_addr = ul; IF (:: bind (STRUCKADDR *) & addr, sizeof (addr)) <0) {sprintf (TEMP, "TCP_CONNECT: BIND FAILED! Errno:% D", wsagetlasterror ()); CloseSocket (SD); Return -1;}}} MEMSET (& Addr, 0, SizeOf (AddR)); UL = inet_addr (HostName); if (ul == 0xfffffffff) {IF ((HP = gethostByname (HostName)) == null) {sprintf (Temp, "gethostByname and inet_addr failed! errno:% D", wsagetlasterror ()) CloseSocket (SD); RETURN-1;} Memcpy (& addr.sin_addr, hp-> h_addr, hp-> h_length);} else addr.sin_addr.s_addr = ul; Addr.sin_Family = AF_INET; addr.sin_port = htons (unsigned short); l = 1; if (/ * f_noblock && * / ioctlsocket (unsigned long *) & l) <0) {CloseSocket SD); RETURN-1;} / * if (STSOCKOPT (SD, Ipproto_TCP, TCP_Nodelay, (Char *) & L, SizeOf (L)) <0) {CloseSocket (SD); Return-1;} * / Time (& T1 ); Int counter = 0; while ((Ret = :: Connect (STRUCKADDR *) & addr, sizeof (addr)))! = 0) {TIME (& T2); if ((t2 -t1)> TIMEOUT ) {CloseSocket (SD); RETURN-1;} peek_message (); int err_no = wsagetlasterror (); if (ret == socket_error) {if (counter > 10) {Sleep (100); counter = 0;} err_no == WSAEISCONN) break;} else if (err_no == WSAEWOULDBLOCK / * || err_no == WSAEINPROGRESS * / || err_no == WSAEALREADY) {continue;} else {closesocket (sd); return -1;}} if (STATUS (SD, "WE", TIMEOUT <0) {sprintf (Temp, "status: ¬ ¬ ¬ ó þþþñ ÷ ê§ ° ü! / n/1¼2é · þþñæ ÷ 3ìðòêç ÷ Ëðð / nçòö ÷ »úμøö ç%% s, ¶ë¿ Úêç · ñ% d / n "" errno =% d ", hostname, port, wsagetlasterror ()); CloseSocket (SD); return -1;} // SD_CONNECT = SD; RETURN SD;} Void CTCP :: Disconnect (INT SD) {if (SD> 0) {CloseSocket (SD); // IF (SD == SD_CONNECT) SD_CONNECT = -1; // IF (SD == SD_ACCEPT) SD_ACCEPT = -1; // if (SD == SD_BIND) SD_BIND = -1;}} INT CTCP :: Send (int SD, CHAR * BUF, INT LEN, INT TIMEOUT) {INT LEN1, LEN_SEND = 0; TIME_T T1, T2; LEN_SEND = 0; TIME (& T1); T2 = T1; INT Counter = 0; while (len_send } Return len_send;} INT CTCP :: RECV (int SD, CHAR * BUF, INT LEN, INT TIMEOUT) {INT LEN1, LEN_RECV; TIME_T T2, T1 LEN_RECV = 0; TIME (& T1); T2 = T1; INT ERR = 0; int counter = 0; while (len_recv IF ((LEN1 = :: RECV (SD, & BUF [LEN_RECV], LEN-LEN_RECV, 0)) <= 0) {Err = wsagetlasterror (); // WriteStat ("Recv Err =% D, LEN1 =% D" , Err, LEN1); if (Timeout == 0) Break; if (len1 == Socket_ERROR && Err == WSAEWOULDBLOCK) {TIME (& T2); IF (Counter > 100) {Sleep (100); counter = 0;} Wsasetlasterror (ERR); RETURN LEN_RECV;} LEN_RECV = LEN1; TIME (& T2);} Wsasetlasterror (ERR); Return Len_Recv;} INT CTCP :: gethostnamebyip (char * ip, char * host) {struct hostent * hp; struct in_addr ul; Host [0] = 0; ul.s_un.s_addr = inet_addr (ip); if (ul.s_un.s_addr == 0xfffffff) return -1; // ip error or ip is hostnamehp = gethostbyaddr ((char *) & ul, 4, AF_INET); if (hp == null) Return -1; // can not get hostname struct (Host, HP-> h_name); Return 0;} INT CTCP :: GET_LOCAL_IP (CHAR * IP) {struct hostent * hp; char host [50], * p; IF (GETHOSTNAME (Host, Sizeof (Host)) <0) RETURN-1; HP = gethostByname (Host); if (hp == null) return -1; p = (char *) hp-> h_addr; wsprintfa (IP, "% d.% d.% d.% d", (int) P [0] & 0xFF, (int) P [1] & 0xFF, (int) P [2] & 0xFF, (int) P [3] & 0xFF); Return 0;} CHAR * CTCP :: GET_REMOTE_IP (INT SD, CHAR * IP) {structure sockaddr_in addr_in; int LEN = sizeof (addr_in); char * p1; IF (SD <0) Return Null; IF (SD, STRUCKADDR *) & Addr_in, & Len) <0) Return NULL; P1 = (Char *) & addr_in.sin_addr; sprintf (ip, "% d.% d .% d.% d "((int) p1 [0]) & 0xFF, ((int) P1 [1]) & 0xFF, (int) P1 [2] & 0xFF, (int) P1 [3] & 0xFF); Return IP;} UNSIGNED SHORT CTCP :: Htons (unsigned short s) {return :: htons (s);} UNSIGNED SHORT CTCP :: NTOHS (Unsigned Short S) {Return :: NTOHS (S); Unsigned long int ctcp :: htonl (unsigned long int L) {return :: HTONL (L); Unsigned long int ctcp :: ntohl (unsigned long int L) {return :: ntohl (l); Float ctcp :: HTONF (FLOAT F) {Unsigned Char * P, P0, P1; IF (htons (1) == 1) RETURN F; P = (unsigned char *) & f; p0 = p [0]; p1 = p [1]; p [0] = P [3]; p [3] = p0; p [1] = p [2]; p [2] = P1; Return f; Float ctcp :: ntohf (float f) {UNSIGNED CHAR * P, P0, P1; IF (NTOHS (1) == 1) Return F; P = (unsigned char *) & f; p0 = p [0]; p1 = p [1]; p [0] = p [3]; p [3] = P0; P [1] = P [2]; P [2] = p1; return f;} Double CTCP :: Htond (double d) {UNSIGNED CHAR * P, P0, P1, P2, P3; IF (htons (1) == 1) RETURN D; P = (unsigned char *) & D; p0 = p [0]; p1 = p [1]; p2 = p [2]; p3 = p [3]; p [0] = P [7]; p [7 ] = p0; p [1] = p [6]; p [6] = p1; p [2] = p [5]; p [5] = p2; p [3] = P [4]; p [ 4] = P3; Return D; Double CTCP :: NTOHD (Double D) {UNSIGNED CHAR * P, P0, P1, P2, P3; IF (NTOHS (1) == 1) RETURN D; P = (unsigned char *) & D; p0 = p [0]; p1 = p [1]; p2 = p [2]; p3 = p [3]; p [0] = P [7]; p [7 ] = p0; p [1] = p [6]; p [6] = p1; p [2] = p [5]; p [5] = p2; p [3] = P [4]; p [ 4] = P3; Return D; Unsigned __int64 ctcp :: htonh (unsigned __INT64 D) {UNSIGNED CHAR * P, P0, P1, P2, P3; IF (htons (1) == 1) RETURN D; P = (unsigned char *) & D; p0 = p [0]; p1 = p [1]; p2 = p [2]; p3 = p [3]; p [0] = P [7]; p [7 ] = p0; p [1] = p [6]; p [6] = p1; p [2] = p [5]; p [5] = p2; p [3] = P [4]; p [ 4] = P3; Return D; Unsigned __int64 ctcp :: ntohh (unsigned __INT64 D) {UNSIGNED CHAR * P, P0, P1, P2, P3; IF (NTOHS (1) == 1) RETURN D; P = (unsigned char *) & D; p0 = p [0]; p1 = p [1]; p2 = p [2]; p3 = p [3]; p [0] = P [7]; p [7 ] = p0; p [1] = p [6]; p [6] = p1; p [2] = p [5]; p [5] = p2; p [3] = P [4]; p [ 4] = P3; Return D; Void ctcp :: peek_message (void) {msg msg; IF (PEEKMESSAGE (& MSG, NULL, 0, 0, PM_Remove) {TranslateMessage (& MSG); DispatchMessage (& MSG);}} INT CTCP :: Bind_Listen (int port, sockaddr_in & addr, long & err) { int sock; sock = socket (AF_INET, SOCK_STREAM, 0); // Create socket addr.sin_family = AF_INET; // Address family Internet addr.sin_port = htons (port); // Assign port 'port' to this socket addr. SIN_ADDR.S_ADDR = HTONL (INADDR_Any); // no destination if (: bind (sock, (lpsockaddr) & addr, sizeof (addr) == SOCKET_ERROR) {CloseSocket (SOCK); err = wsagetlasterror (); return -1 }} F (::}) {CloseSocket (SOCK); Err = wsagetlasterror (); return;} returnitch;} Void CTCP :: Close (int & SD) {Shutdown (SD, 0); CloseSocket (SD); SD = invalid_socket;}