1 // Sun, 18 Jun 2000 2 // Y.Takagi 3 4 #ifdef WIN32 5 #include <winsock.h> 6 #else 7 #include <net/socket.h> 8 #include <net/netdb.h> 9 #ifdef HAVE_ARPA_INET 10 // inet_addr() is not defined in netdb.h anymore under BONE & later 11 #include <arpa/inet.h> 12 #endif 13 #endif // WIN32 14 15 #include <cstdio> 16 #include "Socket.h" 17 #include "SocketStream.h" 18 19 #ifndef INADDR_NONE 20 #define INADDR_NONE 0xffffffff 21 #endif 22 23 #ifdef WIN32 24 #define EADDRINUSE WSAEADDRINUSE 25 #define errno WSAGetLastError() 26 #else 27 #include <errno.h> 28 #endif 29 30 #ifdef WIN32 31 class WIN32SOCKET { 32 public: 33 WIN32SOCKET() 34 { 35 WSADATA winsockdata; 36 WSAStartup(MAKEWORD(1,1), &winsockdata); 37 } 38 ~WIN32SOCKET() 39 { 40 WSACleanup(); 41 } 42 }; 43 44 WIN32SOCKET win32socket; 45 #endif 46 47 Socket::Socket(const char *host, int port) 48 : __sock(-1), __is(NULL), __os(NULL), __error(false) 49 { 50 __host = host; 51 __port = port; 52 __localPort = -1; 53 __error_msg[0] = '\0'; 54 55 open(); 56 } 57 58 Socket::Socket(const char *host, int port, int localPort) 59 : __sock(-1), __is(NULL), __os(NULL), __error(false) 60 { 61 __host = host; 62 __port = port; 63 __localPort = localPort; 64 __error_msg[0] = '\0'; 65 66 open(); 67 } 68 69 Socket::~Socket() 70 { 71 close(); 72 if (__is) { 73 delete __is; 74 } 75 if (__os) { 76 delete __os; 77 } 78 } 79 80 istream &Socket::getInputStream() 81 { 82 if (__is == NULL) { 83 __is = new isocketstream(this); 84 } 85 return *__is; 86 } 87 88 ostream &Socket::getOutputStream() 89 { 90 if (__os == NULL) { 91 __os = new osocketstream(this); 92 } 93 return *__os; 94 } 95 96 void Socket::open() 97 { 98 if (__sock == -1 && !__error) { 99 100 sockaddr_in sin; 101 memset(&sin, 0, sizeof(sin)); 102 103 unsigned long inaddr; 104 hostent *host_info; 105 106 if ((inaddr = inet_addr(__host.c_str())) != INADDR_NONE) { 107 memcpy(&sin.sin_addr, &inaddr, sizeof(inaddr)); 108 sin.sin_family = AF_INET; 109 } else if ((host_info = gethostbyname(__host.c_str())) != NULL) { 110 memcpy(&sin.sin_addr, host_info->h_addr, host_info->h_length); 111 sin.sin_family = host_info->h_addrtype; 112 } else { 113 sprintf(__error_msg, "gethostbyname failed. errno = %d", errno); 114 __error = true; 115 return; 116 } 117 118 if ((__sock = socket(AF_INET, SOCK_STREAM, 0)) == -1) { 119 sprintf(__error_msg, "socket failed. errno = %d", errno); 120 __error = true; 121 } else { 122 if (__localPort >= 0) { 123 sockaddr_in cin; 124 memset(&cin, 0, sizeof(cin)); 125 cin.sin_family = AF_INET; 126 cin.sin_port = htons(__localPort); 127 if (::bind(__sock, (sockaddr *)&cin, sizeof(cin)) != 0) { 128 sprintf(__error_msg, "bind failed. errno = %d", errno); 129 ::close(__sock); 130 __sock = -1; 131 __error = true; 132 } 133 } 134 sin.sin_port = htons(__port); 135 if (::connect(__sock, (sockaddr *)&(sin), sizeof(sin)) != 0) { 136 sprintf(__error_msg, "connect failed. errno = %d", errno); 137 ::close(__sock); 138 __sock = -1; 139 __error = true; 140 } 141 } 142 } 143 } 144 145 void Socket::close() 146 { 147 if (__sock != -1) { 148 ::shutdown(__sock, 2); 149 ::close(__sock); 150 __sock = -1; 151 } 152 } 153 154 bool Socket::fail() const 155 { 156 return __sock == -1 || __error; 157 } 158 159 bool Socket::good() const 160 { 161 return !fail(); 162 } 163 164 bool Socket::operator !() const 165 { 166 return fail(); 167 } 168 169 int Socket::read(char *buffer, int size, int flags) 170 { 171 if (fail()) { 172 size = 0; 173 } else { 174 size = ::recv(__sock, buffer, size, flags); 175 if (size <= 0) { 176 sprintf(__error_msg, "recv failed. errno = %d", errno); 177 __error = true; 178 close(); 179 } 180 } 181 return size; 182 } 183 184 int Socket::write(const char *buffer, int size, int flags) 185 { 186 if (fail()) { 187 size = 0; 188 } else { 189 size = ::send(__sock, buffer, size, flags); 190 if (size <= 0) { 191 sprintf(__error_msg, "send failed. errno = %d", errno); 192 __error = true; 193 close(); 194 } 195 } 196 return size; 197 } 198