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