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
Socket(const char * host,int port)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
Socket(const char * host,int port,int localPort)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
~Socket()43 Socket::~Socket()
44 {
45 close();
46 if (__is) {
47 delete __is;
48 }
49 if (__os) {
50 delete __os;
51 }
52 }
53
getInputStream()54 istream &Socket::getInputStream()
55 {
56 if (__is == NULL) {
57 __is = new isocketstream(this);
58 }
59 return *__is;
60 }
61
getOutputStream()62 ostream &Socket::getOutputStream()
63 {
64 if (__os == NULL) {
65 __os = new osocketstream(this);
66 }
67 return *__os;
68 }
69
open()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
close()119 void Socket::close()
120 {
121 if (__sock != -1) {
122 ::shutdown(__sock, 2);
123 ::close(__sock);
124 __sock = -1;
125 }
126 }
127
fail() const128 bool Socket::fail() const
129 {
130 return __sock == -1 || __error;
131 }
132
good() const133 bool Socket::good() const
134 {
135 return !fail();
136 }
137
operator !() const138 bool Socket::operator !() const
139 {
140 return fail();
141 }
142
read(char * buffer,int size,int flags)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
write(const char * buffer,int size,int flags)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