/*--------------------------------------------------------------------------------------------------------------------------------------------------- Program Listing for: MySocket.cpp Project: socketclass Namespace: c++ ---------------------------------------------------------------------------------------------------------------------------------------------------- */ // MySocket.cpp: implementation of the CMySocket class. // ////////////////////////////////////////////////////////////////////// #include "stdafx.h" #include "securesock.h" #include "MySocket.h" #include <windows.h> #include <winspool.h> #include <string.h> #include <stdio.h> #include <mapi.h> #include <malloc.h> #include <winsock.h> #include "Slot.h" #include "MiscStuff1.h" #ifdef _DEBUG #undef THIS_FILE static char THIS_FILE[]=__FILE__; #define new DEBUG_NEW #endif ////////////////////////////////////////////////////////////////////// // Construction/Destruction ////////////////////////////////////////////////////////////////////// int CMySocket::wsa_inited = 0; char nothing[2]; volatile bool g_inconnect = false; CMySocket::CMySocket() { out_string = NULL; s = 0; bFinished = 0; bError = 0; outbuf = (char *)malloc(200); sockinit(); } CMySocket::CMySocket(char *cserver, unsigned int nport) { out_string = NULL; s = 0; bFinished = 0; bError = 0; outbuf = (char *)malloc(200); sockinit(); sockconnect(cserver, nport); } CMySocket::~CMySocket() { sockclose(); if (outbuf) { free(outbuf); outbuf = NULL; } if (out_string) { free(out_string); out_string = NULL; } } char *CMySocket::sockclose() { if (outbuf) { free(outbuf); outbuf = NULL; } outbuf = (char *)malloc(200); if (s) { if (closesocket(s)) { strcpy(outbuf, "Error with socket close."); return (outbuf); } else { //s = 0; strcpy(outbuf, " "); return (outbuf); } } else { strcpy(outbuf, "invalid socket."); return (outbuf); } } char *CMySocket::sockinit(void) { if (! wsa_inited) { if (outbuf) { free(outbuf); outbuf = NULL; } outbuf = (char *)malloc(200); // using winsock 2.0 if (WSAStartup(MAKEWORD(2, 0), &wsaData)) { strcpy(outbuf, "Trouble starting winsock"); return (outbuf); } wsa_inited = 1; } strcpy(outbuf, " "); return (outbuf); } // for email use SMTP:user@site.com char *CMySocket::sockconnect(char *in_string, int port) { struct sockaddr_in a; struct hostent *h; if (outbuf) { free(outbuf); outbuf = NULL; } if (out_string) { free(out_string); out_string = NULL; } outbuf = (char *)malloc(200); // I use g_inconnect as a sort of semaphore since connecting seems to block on the machine level // causing connect fails when two threads hit this function at once, so if another thread hits and // the first thread is still connecting, I make it wait while (g_inconnect) { TRACE("waiting on socket"); } g_inconnect = true; h = gethostbyname(in_string); if (h==NULL) { // try connecting to IP string if failure to connect to NAME int uPeer[4] ; uPeer[3] = uPeer[2] = uPeer[1] = uPeer[0] = 0; sscanf ( in_string, "%d.%d.%d.%d", &uPeer[0], &uPeer[1], &uPeer[2], &uPeer[3] ) ; // move it into a char array for ::gethostbyaddr() char cPeer[4] ; cPeer[0] = uPeer[0] ; cPeer[1] = uPeer[1] ; cPeer[2] = uPeer[2] ; cPeer[3] = uPeer[3] ; char test_string[255]; sprintf(test_string, "%d.%d.%d.%d", uPeer[0], uPeer[1], uPeer[2], uPeer[3] ) ; //MessageBox(NULL, in_string, "", 0); //MessageBox(NULL, test_string, "", 0); // test see if it connects for a string of type "63.230.230.145" h = ::gethostbyaddr( cPeer, 4, PF_INET); if (h==NULL) { //WSACleanup(); strcpy(outbuf, "both failed: 234 Trouble connecting: bad URL"); ::MessageBox(NULL, outbuf, NULL, MB_OK); bError = 1; g_inconnect = false; return (outbuf); } } a.sin_family = AF_INET; a.sin_port = htons(port); //a.sin_addr.s_addr = inet_addr(in_string); memcpy( &(a.sin_addr.s_addr), h->h_addr, sizeof(int)); s = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); if (s==0) { //WSACleanup(); strcpy(outbuf, "MySocket class error: Trouble creating socket"); ::MessageBox(NULL, outbuf, NULL, MB_OK); g_inconnect = false; return (outbuf); } if (connect(s, (struct sockaddr *)&a, sizeof(a))) { //WSACleanup(); strcpy(outbuf, "1:Trouble with socket: connecting"); //::MessageBox(NULL, outbuf, NULL, MB_OK); bError = 1; g_inconnect = false; return (outbuf); } u_long utemp = 1; if (ioctlsocket (s, FIONBIO, &utemp)) { strcpy(outbuf, "MySocket class error: Trouble setting non-blocking"); ::MessageBox(NULL, outbuf, NULL, MB_OK); bError = 1; g_inconnect = false; return (outbuf); } g_inconnect = false; strcpy(outbuf, " "); return (outbuf); } // for email use SMTP:user@site.com char *CMySocket::sockconnectasync(char *in_string, int port, HWND hwind, long flags, unsigned int nmsg) { struct sockaddr_in a; struct hostent *h; int nret; if (outbuf) { free(outbuf); outbuf = NULL; } if (out_string) { free(out_string); out_string = NULL; } outbuf = (char *)malloc(200); h = gethostbyname(in_string); if (h==NULL) { // try connecting to IP string if failure to connect to NAME int uPeer[4] ; uPeer[3] = uPeer[2] = uPeer[1] = uPeer[0] = 0; sscanf ( in_string, "%d.%d.%d.%d", &uPeer[0], &uPeer[1], &uPeer[2], &uPeer[3] ) ; // move it into a char array for ::gethostbyaddr() char cPeer[4] ; cPeer[0] = uPeer[0] ; cPeer[1] = uPeer[1] ; cPeer[2] = uPeer[2] ; cPeer[3] = uPeer[3] ; char test_string[255]; sprintf(test_string, "%d.%d.%d.%d", uPeer[0], uPeer[1], uPeer[2], uPeer[3] ) ; MessageBox(NULL, in_string, "", 0); MessageBox(NULL, test_string, "", 0); // test see if it connects for a string of type "63.230.230.145" h = ::gethostbyaddr( cPeer, 4, PF_INET); if (h==NULL) { //WSACleanup(); strcpy(outbuf, "both failed: 234 Trouble connecting: bad URL"); return (outbuf); } } a.sin_family = AF_INET; a.sin_port = htons(port); //a.sin_addr.s_addr = inet_addr(in_string); memcpy( &(a.sin_addr.s_addr), h->h_addr, sizeof(int)); s = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); if (s==0) { //WSACleanup(); strcpy(outbuf, "Trouble creating socket."); return (outbuf); } nret = WSAAsyncSelect(s, hwind, nmsg, flags); if (nret == SOCKET_ERROR) { return (strcpy(outbuf, "Trouble with socket: Select function")); } nret = connect(s, (struct sockaddr *)&a, sizeof(a)); if ( nret == SOCKET_ERROR) { int lasterr = WSAGetLastError(); if (lasterr == WSAEWOULDBLOCK) { //MessageBox(NULL,"blocking message", "", 0); // blocking message is okay for now, since sometime a good connect returns this // code for some reason, more testing required } else { sprintf(outbuf, "Trouble with socket, connecting.\nError No:%d", lasterr); return ( outbuf ); } // WSACleanup(); // strcpy(outbuf, "2:Trouble with socket: connecting"); // return (outbuf); } u_long utemp = 1; /* if (ioctlsocket (s, FIONBIO, &utemp)) { strcpy(outbuf, "Trouble setting non-blocking"); return (outbuf); } */ strcpy(outbuf, ""); return (outbuf); } char *CMySocket::sockreceive() { int back, back2; nothing[0] = (char)0; if (bFinished) { ::MessageBox(NULL, "error:receive called on closed socket", NULL, MB_OK); return nothing; } /* fd_set stReadFDS; FD_ZERO(&stReadFDS); FD_SET(s, &stReadFDS); struct timeval stTimeOut; stTimeOut.tv_sec = 0; stTimeOut.tv_usec = 0; int nselect = select(-1, &stReadFDS, NULL, NULL, &stTimeOut); if (nselect == SOCKET_ERROR) { ::MessageBox(NULL, "error on call to select", NULL, MB_OK); bError = 1; return nothing; } bool bReadSet; bReadSet = ! (FD_ISSET(s, &stReadFDS) == 0); */ /* if (! bReadSet ) return out_string; */ myout[0] = (char)0; back2 = recv(s, myout, 1000, MSG_PEEK); back = recv(s, myout, 1000, 0); if (back2 > 0) { //MessageBox(NULL, myout, "", 0); //strncpy(out_string , myout, back); //out_string[back] = (char)0; myout[back] = (char)0; } // this sometimes happens when the socket isn't ready to receive yet (I think) but in that case // we just keep looping in getfileasstring (timeout will eventually show connection to be bad if // the socket never goes into a good receive mode). this whole thing fixes an exotic error if (back2 == -1) { //strcpy(out_string, "0: -1"); //::MessageBox(NULL, "socket receive error, code = -1", NULL, MB_OK); //bFinished = 1; } if (back2 == 0) { //strcpy(out_string, "0: 0"); //if (bReadSet) // bFinished = 1; } /* if (back2 == SOCKET_ERROR) { strcpy(out_string, "0: SOCKET_ERROR with receive unknown type"); TRACE("error code: %i", back); ::MessageBox(NULL, out_string, NULL, MB_OK); bFinished = 1; } */ return myout; } void CMySocket::GetFileAsString(char *file_name, char *host_name, CString *ret_string) { CString string; CString reply_string; TRACE("entering getfileasstring\n"); if (bError) { TRACE("leaving getfileasstring\n"); *ret_string = ""; return; } string.Format("GET %s HTTP/1.1\r\nHost: %s\r\n\r\n", file_name, host_name); socksend(string.GetBuffer(0)); //Sleep(100); if ( ::stopping_threads() ) { bError = true; goto end; } //Sleep(100); double xx; double xy; unsigned long yy; xx = CMiscStuff::GetSeconds(); if (! bError) { int cnt =2; //double x1, x2; MSG message; int n; while (1) { if ( ::stopping_threads() ) { bError = true; break; } /* for (n=0;n<1000;n++) { if (::PeekMessage(&message, NULL, 0, 0, PM_REMOVE)) { ::TranslateMessage(&message); ::DispatchMessage(&message); } } */ Sleep(20); char *response = sockreceive(); if ( response && strlen(response) > 0) { reply_string += response; xx = CMiscStuff::GetSeconds(); if ( strchr(response, '^') ) { TRACE("normal socket finish\n"); bFinished = 1; } } if (bFinished || bError) break; xy = CMiscStuff::GetSeconds(); yy = (unsigned long)(xy - xx); // 5 seconds of inactivity mean probable disconnect or failure of some kind // a normal end will have a caret "^" as a normal end of message indicator if (yy > 10L) { //bFinished = 1; bError = true; TRACE("five second time out reached, aborting receive\n"); break; } } //CString count; //count.Format("%i tries", cnt); //AfxMessageBox(count); } else reply_string = ""; end: TRACE("leaving getfileasstring\n"); *ret_string = reply_string; return; } char *CMySocket::socksend(char *in_string) { int nsize; nsize = strlen(in_string); if (bFinished) { ::MessageBox(NULL, "error:send called on closed socket", NULL, MB_OK); return ""; } if (outbuf) { free(outbuf); outbuf = NULL; } outbuf = (char *)malloc(200); if (send(s, in_string, nsize, 0) == SOCKET_ERROR) { //WSACleanup(); strcpy(outbuf, "Trouble with socket: connecting"); ::MessageBox(NULL, outbuf, NULL, MB_OK); bError = 1; return (outbuf); } strcpy(outbuf, " "); return (outbuf); } int CMySocket::sockcleanup(void) { if (out_string) { free(out_string); out_string = NULL; } if (outbuf) { free(outbuf); outbuf = NULL; } // we may or may not want to close socket library, and sometimes this also // causes GPF's. //WSACleanup(); return 1; } void CMySocket::sockwsacleanup(void) { WSACleanup(); } // for email use SMTP:user@site.com char *CMySocket::gettextback(char *in_string, int nsleep) { struct sockaddr_in a; struct hostent *h; WSADATA wsaData; if (outbuf) { free(outbuf); } if (out_string) { free(out_string); out_string = NULL; } outbuf = (char *)malloc(200); if (WSAStartup(0x101, &wsaData)) { strcpy(outbuf, "Trouble starting winsock"); return (outbuf); } h = gethostbyname("www.sboe.state.az.us"); if (h==NULL) { WSACleanup(); strcpy(outbuf, "Trouble connecting"); return (outbuf); } a.sin_family = AF_INET; a.sin_port = htons(80); memcpy( &(a.sin_addr.s_addr), h->h_addr, sizeof(int)); s = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); if (s==0) { WSACleanup(); strcpy(outbuf, "Trouble creating socket"); return (outbuf); } if (connect(s, (struct sockaddr *)&a, sizeof(a))) { WSACleanup(); strcpy(outbuf, "Trouble with socket: connecting"); return (outbuf); } int nsize; nsize = strlen(in_string); if (send(s, in_string, nsize, 0) == SOCKET_ERROR) { WSACleanup(); strcpy(outbuf, "Trouble with socket: connecting"); return (outbuf); } if (out_string) { free(out_string); out_string = NULL; } char myout[1001]; char *offset; offset = myout; int back; int back2; out_string = (char *)malloc(1001); Sleep(nsleep); back2 = recv(s, myout, 1000, MSG_PEEK); back = recv(s, myout, 1000, 0); /* sprintf(mout, "back:%i", back); MessageBox(NULL, mout, "", 0); sprintf(mout, "back2:%i", back2); MessageBox(NULL, mout, "", 0); if (back2>0) { myout[back2] = '\0'; } MessageBox(NULL, myout, "", 0); */ //myout[back] = '\0'; if (back2 > 0) { //MessageBox(NULL, myout, "", 0); strncpy(out_string , myout, back); out_string[back] = (char)0; } if (back == -1) { strcpy(out_string, "0: -1"); } if (back == 0) { strcpy(out_string, "0: 0"); } if (back == SOCKET_ERROR) { strcpy(out_string, "0: SOCKET_ERROR"); } return out_string; } char *CMySocket::nextone(void) { char myout[1001]; int back2, back; if (out_string) { free(out_string); out_string = NULL; } out_string = (char *)malloc(1001); back2 = recv(s, myout, 1000, MSG_PEEK); back = recv(s, myout, 1000, 0); /* sprintf(mout, "back:%i", back); MessageBox(NULL, mout, "", 0); sprintf(mout, "back2:%i", back2); MessageBox(NULL, mout, "", 0); sprintf(mout, "back:%i", back); MessageBox(NULL, mout, "", 0); sprintf(mout, "back2:%i", back2); MessageBox(NULL, mout, "", 0); if (back2>0) { myout[back2] = '\0'; } MessageBox(NULL, myout, "", 0); */ //myout[back] = '\0'; if (back2 > 0) { strncpy(out_string , myout, back); out_string[back] = (char)0; } if (back2 == -1) { strcpy(out_string, "0: -1"); } if (back2 == 0) { strcpy(out_string, "0: 0"); } if (back2 == SOCKET_ERROR) { strcpy(out_string, "0: SOCKET_ERROR"); } return out_string; } int CMySocket::cleanup(void) { if (out_string) { free(out_string); out_string = NULL; } WSACleanup(); return 1; }