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