2 #include <sys/socket.h>
5 #include <msp/io/poll.h>
6 #include <msp/strings/formatter.h>
7 #include "streamsocket.h"
13 Used by StreamListenSocket to construct a new socket from accept.
15 StreamSocket::StreamSocket(SocketHandle h, const SockAddr &paddr):
20 WSAEventSelect(handle, event, FD_READ|FD_CLOSE);
22 set_events(IO::P_INPUT);
26 Constructs a new StreamSocket.
28 StreamSocket::StreamSocket(Family af, int proto):
29 Socket(af, SOCK_STREAM, proto),
34 Checks the status of an ongoing connection attempt. If the connection fails
35 with an error, an exception is thrown.
37 @return 0 if the connection finished, 1 if not
39 int StreamSocket::poll_connect(const Time::TimeDelta &timeout)
43 throw InvalidState("No connection attempt going on");
45 int res=poll(*this, IO::P_OUTPUT, timeout);
48 throw Exception(format("Connection polling failed: %d", WSAGetLastError()));
50 throw SystemError("Connection polling failed", errno);
57 socklen_t len=sizeof(int);
58 get_option(SOL_SOCKET, SO_ERROR, &err, &len);
62 set_events(IO::P_NONE);
64 throw Exception(format("Connection failed: %d", err));
66 throw SystemError("Connection failed", err);
71 WSAEventSelect(handle, event, FD_READ|FD_CLOSE);
73 set_events(IO::P_INPUT);
84 Connects the socket to a remote address. In non-blocking mode, this function
85 may return before the connection is finished. The caller must then use either
86 the poll_connect function or an EventDispatcher to determine when the
87 connection is finished.
89 @return 0 if the connection finished, 1 if it is in progress
91 int StreamSocket::connect(const SockAddr &addr)
96 throw InvalidState("Socket is already connected");
99 socklen_t size=addr.fill_sockaddr(sa);
102 int err=WSAConnect(handle, reinterpret_cast<sockaddr *>(&sa), size, 0, 0, 0, 0);
103 if(err==SOCKET_ERROR)
105 int err_code=WSAGetLastError();
106 if(err_code==WSAEWOULDBLOCK)
109 WSAEventSelect(handle, event, FD_CONNECT);
110 set_events(IO::P_OUTPUT);
113 throw Exception(format("Unable to connect: %d", err_code));
116 int err=::connect(handle, reinterpret_cast<sockaddr *>(&sa), size);
119 if(errno==EINPROGRESS)
122 set_events(IO::P_OUTPUT);
125 throw SystemError("Unable to connect", errno);
130 peer_addr=addr.copy();
133 size=sizeof(sockaddr_storage);
134 getsockname(handle, reinterpret_cast<sockaddr *>(&sa), &size);
135 local_addr=SockAddr::create(sa);
140 set_events(IO::P_INPUT);
141 signal_connect_finished.emit(0);
147 void StreamSocket::on_event(IO::PollEvent ev)
149 //cout<<"StreamSocket::on_event "<<ev<<'\n';
150 if((ev&(IO::P_OUTPUT|IO::P_ERROR)) && connecting)
153 socklen_t len=sizeof(err);
154 get_option(SOL_SOCKET, SO_ERROR, &err, &len);
158 signal_connect_finished.emit(err);
167 WSAEventSelect(handle, event, FD_READ|FD_CLOSE);
169 set_events((err==0) ? IO::P_INPUT : IO::P_NONE);