#include "SocketObject.h" #include #include #include #include #include #include #if defined(__msdos__) || defined(WIN32) SocketObject::SocketObject(void) { #ifdef __SOCKET_OBJECT_DEBUG std::cout << "Windows SocketObject Konstruktor" << std::endl; #endif WSADATA wsaData; WORD wVersionRequested; wVersionRequested = MAKEWORD( 2, 0 ); _skSocket = INVALID_SOCKET; WSAStartup(wVersionRequested, &wsaData); } SocketObject::SocketObject(SocketObject& sk) { WSADATA wsaData; WORD wVersionRequested; wVersionRequested = MAKEWORD( 2, 0 ); _skSocket = sk._skSocket; sk._skSocket = INVALID_SOCKET; WSAStartup(wVersionRequested, &wsaData); } SocketObject::~SocketObject(void) { Disconnect(); } #endif void SocketObject::setBlockingMode(bool nonblock) { int errorCode = 0; #if defined(__msdos__) || defined(WIN32) u_long iMode = 1; if (!nonblock) iMode=0; if (0 != ioctlsocket(_skSocket, FIONBIO, &iMode)) { errorCode = WSAGetLastError(); cout << "Set blocking mode ("< bind(_skSocket, (sockaddr*) &saServerAddress, sizeof(sockaddr))) { // Socket will nicht mehr lesen und schreiben shutdown(_skSocket,2); #ifdef __SOCKET_OBJECT_DEBUG std::cout << "Error: on bind" << std::endl; #endif return -1; } else { return 0; } #endif } int SocketObject::Listen( void ) { // lauscht bei _skSocket, max Warteschlange = 2 return listen(_skSocket, 2); // WIN32 : ,32 } bool SocketObject::Accept(SocketObject &skAcceptSocket) { struct sockaddr_in saClientAddress; int iClientSize = sizeof(sockaddr_in); #if defined(__msdos__) || defined(WIN32) skAcceptSocket._skSocket = accept(_skSocket, (struct sockaddr*)&saClientAddress, &iClientSize); return !( skAcceptSocket._skSocket == INVALID_SOCKET); #else skAcceptSocket._skSocket = accept( _skSocket, (sockaddr*) &saClientAddress,(socklen_t*) &iClientSize); return !( skAcceptSocket._skSocket == -1); #endif } bool SocketObject::Connect(const char* szServerAddress, unsigned short int iPort, bool nonblock) { #if defined(__msdos__) || defined(WIN32) struct sockaddr_in server_addr; LPHOSTENT lpHost; int error; // open the socket _skSocket = socket(AF_INET, SOCK_STREAM, 0); if (_skSocket == INVALID_SOCKET) return false; u_long iMode = 0; if (nonblock) iMode = 1; ioctlsocket(_skSocket, FIONBIO, &iMode); memset(&server_addr,0,sizeof(struct sockaddr_in)); server_addr.sin_family = AF_INET; server_addr.sin_addr.s_addr = inet_addr(szServerAddress); if (server_addr.sin_addr.s_addr == INADDR_NONE) { lpHost = gethostbyname(szServerAddress); if (lpHost != NULL) { server_addr.sin_addr.s_addr = ((LPIN_ADDR)lpHost->h_addr)->s_addr; } else return false; } server_addr.sin_port = htons(iPort); error = connect(_skSocket, (struct sockaddr*)&server_addr, sizeof(sockaddr)); if (error == SOCKET_ERROR) { Disconnect(); return false; } return true; #else struct sockaddr_in server_addr; int status; // create socket _skSocket = socket(AF_INET, SOCK_STREAM, 0); if (_skSocket < 0) return false; if (nonblock) fcntl(_skSocket, F_SETFL, O_NONBLOCK); // initialize der sockaddr_in- Struktur memset(&server_addr, 0, sizeof(struct sockaddr_in)); server_addr.sin_family = AF_INET; server_addr.sin_addr.s_addr = inet_addr(szServerAddress); server_addr.sin_port = htons(iPort); // connect to server status = connect(_skSocket, (struct sockaddr*)&server_addr, sizeof(sockaddr)); if (status < 0) { shutdown(_skSocket,2); return false; } return true; #endif } bool SocketObject::Connect(const std::string szServerAddress, unsigned short int iPort, bool nonblock) { return Connect((char*) szServerAddress.c_str(), iPort, nonblock); } void SocketObject::Disconnect() { #if defined(__msdos__) || defined(WIN32) if (_skSocket != INVALID_SOCKET) { closesocket(_skSocket); _skSocket = INVALID_SOCKET; } #else close(_skSocket); #endif } int SocketObject::Recv(char *szBuffer, int iBufferLength, int iFlags) { return recv(_skSocket, szBuffer, iBufferLength, iFlags); } int SocketObject::Recv (std::string& s) { char buf [MAXRECV+1]; // std::cout << WSAGetLastError() << " in SocketObject::Recv, vor recv" << std::endl; s = ""; memset(buf, 0, MAXRECV+1); int status = Recv(buf, MAXRECV, 0); switch (status) { case -1: #ifdef __SOCKET_OBJECT_DEBUG std::cout << "status: -1 errno: " << errno << " in SocketObject::Recv" << std::endl; #endif break; case 0: break; default: s = buf; // strip the (expected) CRLF if(s.length() == 1) { if(s[s.length()-1]=='\n' || s[s.length()-1]=='\r') s.resize(s.length()-1); } else if(s.length() >= 2) { if(s[s.length()-1]=='\n' && s[s.length()-2]=='\r') s.resize(s.length()-2); else if(s[s.length()-1]=='\n' || s[s.length()-1]=='\r') s.resize(s.length()-1); } break; } return status; } int SocketObject::receiveLine(char* array, int arraySize) { char r; int pos = 0; while (pos 0) { array[pos]='\0'; return pos; } }else { array[pos] = r; pos++; } } return pos; } std::string SocketObject::receiveLine() { std::string ret; char r; while (1) { //This will not work under windows if the blocking mode is non-blocking // -1 will indicate that there is no value, it is not an error !!! //http://msdn.microsoft.com/en-us/library/ms740121(VS.85).aspx //For linux see: //http://linux.about.com/library/cmd/blcmdl2_recv.htm //If no messages are available at the socket, the receive calls wait for a message to arrive, //unless the socket is nonblocking (see fcntl(2)) in which case the value -1 is returned and // the external variable errno set to EAGAIN. switch(recv(_skSocket, &r, 1, 0)) { case 0: // not connected anymore; return SOCKETOBJECT_NOT_CONNECTED; case -1: // error return SOCKETOBJECT_RECV_ERROR; } // check for carriage return or line feed (MAC: CR, Linux: LF, Windows: CRLF) if ((r == char(13)) || (r == char(10))) { if (ret.length() > 0) return ret; } else { ret += r; } } } int SocketObject::Send(const char *szBuffer, int iBufferLength, int iFlags) { return send(_skSocket,szBuffer,iBufferLength, iFlags); } int SocketObject::Send (const std::string s) { std::string str = s; // add the (expected) CRLF if(str == "") { str = "\n\r"; } else if(str.size() == 1) { if(str[0] == '\r') { str = "\n\r"; } else if(str[0] != '\n') { str += "\n\r"; } } else if(str.size() >= 2) { if(str[str.length()-1] != '\n' || str[str.length()-2]!='\r') { str += "\n\r"; } } #if defined(__msdos__) || defined(WIN32) return Send((char*) str.c_str(), (int) str.size(), 0); #else return Send((char*) str.c_str(), (int) str.size(), (int) MSG_NOSIGNAL); #endif }