1 /*
2  *
3  *  C++ Portable Types Library (PTypes)
4  *  Version 2.1.1  Released 27-Jun-2007
5  *
6  *  Copyright (C) 2001-2007 Hovik Melikyan
7  *
8  *  http://www.melikyan.com/ptypes/
9  *
10  */
11 
12 #ifdef WIN32
13 #  include <winsock2.h>
14 #else
15 #  include <sys/time.h>
16 #  include <sys/types.h>
17 #  include <sys/socket.h>
18 #  include <netinet/in.h>
19 #  include <arpa/inet.h>
20 #  include <netdb.h>
21 #  include <unistd.h>
22 #  include <time.h>
23 #endif
24 
25 
26 #include "pinet.h"
27 
28 
29 PTYPES_BEGIN
30 
31 
32 //
33 // ipstmserver
34 //
35 
36 
ipstmserver()37 ipstmserver::ipstmserver()
38     : ipsvbase(SOCK_STREAM)
39 {
40 }
41 
42 
~ipstmserver()43 ipstmserver::~ipstmserver()
44 {
45     close();
46 }
47 
48 
dobind(ipbindinfo * b)49 void ipstmserver::dobind(ipbindinfo* b)
50 {
51 #ifndef WIN32
52     // set SO_REAUSEADDR to true, unix only. on windows this option causes
53     // the previous owner of the socket to give up, which is not desirable
54     // in most cases, neither compatible with unix.
55     int one = 1;
56     if (::setsockopt(b->handle, SOL_SOCKET, SO_REUSEADDR,
57             (sockval_t)&one, sizeof(one)) != 0)
58         error(*b, usockerrno(), "Can't reuse local address");
59 #endif
60 
61     // set up sockaddr_in and try to bind it to the socket
62     sockaddr_in sa;
63     memset(&sa, 0, sizeof(sa));
64     sa.sin_family = AF_INET;
65     sa.sin_port = htons(ushort(b->get_port()));
66     sa.sin_addr.s_addr = b->get_ip();
67 
68     if (::bind(b->handle, (sockaddr*)&sa, sizeof(sa)) != 0)
69         error(*b, usockerrno(), "Couldn't bind address");
70 
71     if (::listen(b->handle, SOMAXCONN) != 0)
72         error(*b, usockerrno(), "Couldn't listen on socket");
73 }
74 
75 
poll(int i,int timeout)76 bool ipstmserver::poll(int i, int timeout)
77 {
78     if (!active)
79         open();
80     return dopoll(&i, timeout);
81 }
82 
83 
serve(ipstream & client,int i,int timeout)84 bool ipstmserver::serve(ipstream& client, int i, int timeout)
85 {
86     if (!active)
87         open();
88 
89     client.cancel();
90     if (dopoll(&i, timeout))
91     {
92         // connect the ipstream object to the client requesting the connection
93         client.svsocket = get_addr(i).handle;
94         client.open();
95         return true;
96     }
97     return false;
98 }
99 
100 
101 PTYPES_END
102