libsocket
streamclient.cpp
Go to the documentation of this file.
1 /*
2  The committers of the libsocket project, all rights reserved
3  (c) 2012, dermesser <lbo@spheniscida.de>
4 
5  Redistribution and use in source and binary forms, with or without
6  modification, are permitted provided that the following conditions are met:
7 
8  1. Redistributions of source code must retain the above copyright notice,
9  this list of conditions and the following disclaimer.
10  2. Redistributions in binary form must reproduce the above copyright notice,
11  this list of conditions and the following disclaimer in the documentation
12  and/or other materials provided with the distribution.
13 
14  THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS “AS IS” AND ANY
15  EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
16  WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
17  DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY
18  DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
19  (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
20  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
21  ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
23  SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24 
25 */
26 
36 #include <string.h>
37 #include <unistd.h>
38 #include <memory>
39 #include <string>
40 
41 #include <conf.h>
42 #include <libinetsocket.h>
43 #include <exception.hpp>
44 #include <streamclient.hpp>
45 
46 namespace libsocket {
50 stream_client_socket::stream_client_socket() : shut_rd(false), shut_wr(false) {}
51 
64 ssize_t stream_client_socket::rcv(void* buf, size_t len, int flags) {
65  ssize_t recvd;
66 
67  if (shut_rd == true)
68  throw socket_exception(
69  __FILE__, __LINE__,
70  "stream_client_socket::rcv() - Socket has already been shut down!",
71  false);
72 
73  if (sfd == -1)
74  throw socket_exception(
75  __FILE__, __LINE__,
76  "stream_client_socket::rcv() - Socket is not connected!", false);
77 
78  if (buf == NULL || len == 0)
79  throw socket_exception(
80  __FILE__, __LINE__,
81  "stream_client_socket::rcv() - Buffer or length is null!", false);
82 
83  memset(buf, 0, len);
84 
85  if (-1 == (recvd = ::recv(sfd, buf, len, flags))) {
86  if (is_nonblocking && errno == EWOULDBLOCK)
87  return -1;
88  else
89  throw socket_exception(
90  __FILE__, __LINE__,
91  "stream_client_socket::rcv() - Error while reading!");
92  }
93 
94  return recvd;
95 }
96 
115  ssize_t read_bytes;
116 
117  if (sock.shut_rd == true)
118  throw socket_exception(__FILE__, __LINE__,
119  "stream_client_socket::operator>>(std::string) "
120  "- Socket has already been shut down!",
121  false);
122 
123  using std::unique_ptr;
124  unique_ptr<char[]> buffer(new char[dest.size()]);
125 
126  memset(buffer.get(), 0, dest.size());
127 
128  if (sock.sfd == -1) {
129  throw socket_exception(__FILE__, __LINE__,
130  ">>(std::string) input: Socket not connected!",
131  false);
132  }
133 
134  if (-1 == (read_bytes = read(sock.sfd, buffer.get(), dest.size()))) {
135  if (sock.is_nonblocking && errno == EWOULDBLOCK) {
136  dest.clear();
137  return sock;
138  } else
139  throw socket_exception(
140  __FILE__, __LINE__,
141  ">>(std::string) input: Error while reading!");
142  }
143 
144  if (read_bytes < static_cast<ssize_t>(dest.size()))
145  dest.resize(read_bytes); // So the client doesn't print content more
146  // than one time and it can check if the
147  // string's length is 0 (end of transmission)
148 
149  dest.assign(buffer.get(), read_bytes);
150 
151  return sock;
152 }
153 
154 // O
155 
171  if (sock.shut_wr == true)
172  throw socket_exception(__FILE__, __LINE__,
173  "stream_client_socket::operator<<(const char*) "
174  "- Socket has already been shut down!",
175  false);
176  if (sock.sfd == -1)
177  throw socket_exception(__FILE__, __LINE__,
178  "<<(const char*) output: Socket not connected!",
179  false);
180  if (str == NULL)
181  throw socket_exception(__FILE__, __LINE__,
182  "<<(const char*) output: Null buffer given!",
183  false);
184 
185  size_t len = strlen(str);
186 
187  if (-1 == write(sock.sfd, str, len))
188  throw socket_exception(__FILE__, __LINE__,
189  "<<(const char*) output: Write failed!");
190 
191  return sock;
192 }
193 
209  const string& str) {
210  if (sock.shut_wr == true)
211  throw socket_exception(__FILE__, __LINE__,
212  "stream_client_socket::operator<<(std::string) "
213  "- Socket has already been shut down!",
214  false);
215  if (sock.sfd == -1)
216  throw socket_exception(__FILE__, __LINE__,
217  "<<(std::string) output: Socket not connected!",
218  false);
219 
220  if (-1 == write(sock.sfd, str.c_str(), str.size()))
221  throw socket_exception(__FILE__, __LINE__,
222  "<<(std::string) output: Write failed!");
223 
224  return sock;
225 }
226 
239 ssize_t stream_client_socket::snd(const void* buf, size_t len, int flags) {
240  ssize_t snd_bytes;
241 
242  if (shut_wr == true)
243  throw socket_exception(
244  __FILE__, __LINE__,
245  "stream_client_socket::snd() - Socket has already been shut down!",
246  false);
247  if (sfd == -1)
248  throw socket_exception(
249  __FILE__, __LINE__,
250  "stream_client_socket::snd() - Socket not connected!", false);
251  if (buf == NULL || len == 0)
252  throw socket_exception(
253  __FILE__, __LINE__,
254  "stream_client_socket::snd() - Buffer or length is null!", false);
255 
256  if (-1 == (snd_bytes = ::send(sfd, buf, len, flags))) {
257  if (is_nonblocking && errno == EWOULDBLOCK)
258  return -1;
259  else
260  throw socket_exception(
261  __FILE__, __LINE__,
262  "stream_client_socket::snd() - Error while sending");
263  }
264 
265  return snd_bytes;
266 }
267 
276  int u_method = 0; // unix flags
277 
278  // Already shut down using this method...
279  if ((method & (LIBSOCKET_READ | LIBSOCKET_WRITE)) && (shut_rd == true) &&
280  (shut_wr == true))
281  return;
282  if ((method & LIBSOCKET_READ) && (shut_rd == true)) return;
283  if ((method & LIBSOCKET_WRITE) && (shut_wr == true)) return;
284 
285  if (method == (LIBSOCKET_READ | LIBSOCKET_WRITE))
286  u_method = SHUT_RDWR;
287  else if (method == LIBSOCKET_READ)
288  u_method = SHUT_RD;
289  else if (method == LIBSOCKET_WRITE)
290  u_method = SHUT_WR;
291  else // With no valid combination
292  return;
293 
294  if (0 >
295  ::shutdown(sfd, u_method)) // It's equal whether we use this or
296  // its brother from libunixsocket
297  {
298  throw socket_exception(
299  __FILE__, __LINE__,
300  "stream_client_socket::shutdown() - Could not shutdown socket");
301  }
302 
303  if (method & LIBSOCKET_READ) shut_rd = true;
304  if (method & LIBSOCKET_WRITE) shut_wr = true;
305 }
306 } // namespace libsocket
int sfd
sfd is the sockets API file descriptor
Definition: socket.hpp:74
Generic socket for active stream sockets (TCP client sockets, UNIX Stream clients)
void shutdown(int method=LIBSOCKET_WRITE)
Shut a socket down.
ssize_t rcv(void *buf, size_t len, int flags=0)
Receive data from socket.
ssize_t snd(const void *buf, size_t len, int flags=0)
Send data to socket.
stream_client_socket()
Void constructor.
Contains all functions available in the C libsocket.
Contains libsocket elements.
Definition: dgramclient.hpp:41
dgram_client_socket & operator>>(dgram_client_socket &sock, string &dest)
Receive data from connected datagram socket.
Definition: dgramclient.cpp:95
dgram_client_socket & operator<<(dgram_client_socket &sock, const char *str)
Send data to connected peer.
This class is instantiated and thrown when an error occurs. If there's an error somewhere in libsocke...
Definition: exception.hpp:52