libsocket
inetserverstream.cpp
Go to the documentation of this file.
1 #include <string.h>
2 #include <memory>
3 #include <string>
4 
5 /*
6  The committers of the libsocket project, all rights reserved
7  (c) 2012, dermesser <lbo@spheniscida.de>
8 
9  Redistribution and use in source and binary forms, with or without
10  modification, are permitted provided that the following conditions are met:
11 
12  1. Redistributions of source code must retain the above copyright notice,
13  this list of conditions and the following disclaimer.
14  2. Redistributions in binary form must reproduce the above copyright notice,
15  this list of conditions and the following disclaimer in the documentation
16  and/or other materials provided with the distribution.
17 
18  THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS “AS IS” AND ANY
19  EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
20  WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
21  DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY
22  DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
23  (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
24  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
25  ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
27  SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28 
29 */
30 
42 #include <conf.h>
43 
44 #include <libinetsocket.h>
45 #include <exception.hpp>
46 #include <inetclientstream.hpp>
47 #include <inetserverstream.hpp>
48 
49 #include <fcntl.h>
50 #ifndef SOCK_NONBLOCK
51 #define SOCK_NONBLOCK O_NONBLOCK
52 #endif
53 
54 namespace libsocket {
55 using std::string;
56 
61 
73  const char* bindport, int proto_osi3,
74  int flags) {
75  setup(bindhost, bindport, proto_osi3, flags);
76 }
77 
89  const string& bindport, int proto_osi3,
90  int flags) {
91  setup(bindhost, bindport, proto_osi3, flags);
92 }
93 
105 void inet_stream_server::setup(const char* bindhost, const char* bindport,
106  int proto_osi3, int flags) {
107  if (sfd != -1)
108  throw socket_exception(__FILE__, __LINE__,
109  "inet_stream_server::inet_stream_server() - "
110  "already bound and listening!",
111  false);
112  if (bindhost == 0 || bindport == 0)
113  throw socket_exception(__FILE__, __LINE__,
114  "inet_stream_server::inet_stream_server() - at "
115  "least one bind argument invalid!",
116  false);
117  if (-1 == (sfd = create_inet_server_socket(
118  bindhost, bindport, LIBSOCKET_TCP, proto_osi3, flags)))
119  throw socket_exception(__FILE__, __LINE__,
120  "inet_stream_server::inet_stream_server() - "
121  "could not create server socket!");
122 
123  host = string(bindhost);
124  port = string(bindport);
125 
126  is_nonblocking = flags & SOCK_NONBLOCK;
127 }
128 
140 void inet_stream_server::setup(const string& bindhost, const string& bindport,
141  int proto_osi3, int flags) {
142  if (sfd != -1)
143  throw socket_exception(__FILE__, __LINE__,
144  "inet_stream_server::inet_stream_server() - "
145  "already bound and listening!",
146  false);
147  if (bindhost.empty() || bindport.empty())
148  throw socket_exception(__FILE__, __LINE__,
149  "inet_stream_server::inet_stream_server() - at "
150  "least one bind argument invalid!",
151  false);
152  if (-1 ==
153  (sfd = create_inet_server_socket(bindhost.c_str(), bindport.c_str(),
154  LIBSOCKET_TCP, proto_osi3, flags)))
155  throw socket_exception(__FILE__, __LINE__,
156  "inet_stream_server::inet_stream_server() - "
157  "could not create server socket!");
158 
159  host = string(bindhost);
160  port = string(bindport);
161 
162  is_nonblocking = flags & SOCK_NONBLOCK;
163 }
164 
177 inet_stream* inet_stream_server::accept(int numeric, int accept_flags) {
178  return accept2(numeric, accept_flags).release();
179 }
180 
192 unique_ptr<inet_stream> inet_stream_server::accept2(int numeric,
193  int accept_flags) {
194  if (sfd < 0)
195  throw socket_exception(
196  __FILE__, __LINE__,
197  "inet_stream_server::accept() - stream server socket is not in "
198  "listening state -- please call first setup()!");
199 
200  using std::unique_ptr;
201  unique_ptr<char[]> src_host(new char[1024]);
202  unique_ptr<char[]> src_port(new char[32]);
203 
204  memset(src_host.get(), 0, 1024);
205  memset(src_port.get(), 0, 32);
206 
207  int client_sfd;
208  unique_ptr<inet_stream> client(new inet_stream);
209 
210  if (-1 == (client_sfd = accept_inet_stream_socket(sfd, src_host.get(), 1023,
211  src_port.get(), 31,
212  numeric, accept_flags))) {
213  if (!is_nonblocking && errno != EWOULDBLOCK) {
214  throw socket_exception(
215  __FILE__, __LINE__,
216  "inet_stream_server::accept() - could not accept new "
217  "connection on stream server socket!");
218  } else {
219  return nullptr; // Only return NULL but don't throw an exception if
220  // the socket is nonblocking
221  }
222  }
223 
224  client->sfd = client_sfd;
225  client->host =
226  string(src_host.get()); // these strings are destructed automatically
227  // when the returned object is deleted.
228  // (http://stackoverflow.com/a/6256543)
229  client->port = string(src_port.get()); //
230  client->proto = proto;
231 
232  return client;
233 }
234 
235 const string& inet_stream_server::getbindhost(void) { return gethost(); }
236 
237 const string& inet_stream_server::getbindport(void) { return getport(); }
238 } // namespace libsocket
Contains libsocket elements.
Definition: dgramclient.hpp:41
unique_ptr< inet_stream > accept2(int numeric=0, int accept_flags=0)
Accept a connection and return a socket connected to the client.
int create_inet_server_socket(const char *bind_addr, const char *bind_port, char proto_osi4, char proto_osi3, int flags)
Create a TCP or UDP server socket.
This class is instantiated and thrown when an error occurs. If there's an error somewhere in libsocke...
Definition: exception.hpp:52
Provides TCP/IP client sockets. This class is the most used socket class in libsocket++....
void setup(const char *bindhost, const char *bindport, int proto_osi3, int flags=0)
Set up a server socket.
const string & getport(void) const
Definition: inetbase.cpp:65
inet_stream * accept(int numeric=0, int accept_flags=0)
Accept a connection and return a socket connected to the client.
int accept_inet_stream_socket(int sfd, char *src_host, size_t src_host_len, char *src_service, size_t src_service_len, int flags, int accept_flags)
Accept a connection attempt on a server socket.
inet_stream_server(void)
Void constructor; don't forget to setup() the socket before use!
string port
The port we're bound or connected to.
Definition: inetbase.hpp:57
int sfd
sfd is the sockets API file descriptor
Definition: socket.hpp:74
int proto
Which internet protocol version we're using.
Definition: inetbase.hpp:59
const string & gethost(void) const
Definition: inetbase.cpp:59
string host
The address we're bound or connected to.
Definition: inetbase.hpp:55
Contains all functions available in the C libsocket.