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