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 25Socket::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 36Socket::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 47Socket::~Socket() 48{ 49 close(); 50 if (__is) { 51 delete __is; 52 } 53 if (__os) { 54 delete __os; 55 } 56} 57 58istream &Socket::getInputStream() 59{ 60 if (__is == NULL) { 61 __is = new isocketstream(this); 62 } 63 return *__is; 64} 65 66ostream &Socket::getOutputStream() 67{ 68 if (__os == NULL) { 69 __os = new osocketstream(this); 70 } 71 return *__os; 72} 73 74void 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 123void Socket::close() 124{ 125 if (__sock != -1) { 126 ::shutdown(__sock, 2); 127 ::close(__sock); 128 __sock = -1; 129 } 130} 131 132bool Socket::fail() const 133{ 134 return __sock == -1 || __error; 135} 136 137bool Socket::good() const 138{ 139 return !fail(); 140} 141 142bool Socket::operator !() const 143{ 144 return fail(); 145} 146 147int 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 162int 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