3 This file is part of libmspnet
4 Copyright © 2008 Mikkosoft Productions, Mikko Rasa
5 Distributed under the LGPL
9 #include <sys/socket.h>
12 #include <msp/io/poll.h>
13 #include <msp/strings/formatter.h>
14 #include "streamsocket.h"
20 Constructs a new StreamSocket.
22 StreamSocket::StreamSocket(Family af, int proto):
23 Socket(af, SOCK_STREAM, proto),
28 Checks the status of an ongoing connection attempt. If the connection fails
29 with an error, an exception is thrown.
31 @return 0 if the connection finished, 1 if not
33 int StreamSocket::poll_connect(const Time::TimeDelta &timeout)
37 throw InvalidState("No connection attempt going on");
39 int res=poll(*this, IO::P_OUTPUT, timeout);
42 throw Exception(format("Connection polling failed: %d", WSAGetLastError()));
44 throw SystemError("Connection polling failed", errno);
51 socklen_t len=sizeof(int);
52 get_option(SOL_SOCKET, SO_ERROR, &err, &len);
56 set_events(IO::P_NONE);
58 throw Exception(format("Connection failed: %d", err));
60 throw SystemError("Connection failed", err);
65 WSAEventSelect(handle, event, FD_READ|FD_CLOSE);
67 set_events(IO::P_INPUT);
78 Connects the socket to a remote address. In non-blocking mode, this function
79 may return before the connection is finished. The caller must then use either
80 the poll_connect function or an EventDispatcher to determine when the
81 connection is finished.
83 @return 0 if the connection finished, 1 if it is in progress
85 int StreamSocket::connect(const SockAddr &addr)
90 throw InvalidState("Socket is already connected");
93 socklen_t size=addr.fill_sockaddr(sa);
96 int err=WSAConnect(handle, &sa, size, 0, 0, 0, 0);
99 int err_code=WSAGetLastError();
100 if(err_code==WSAEWOULDBLOCK)
103 WSAEventSelect(handle, event, FD_CONNECT);
104 set_events(IO::P_OUTPUT);
107 throw Exception(format("Unable to connect: %d", err_code));
110 int err=::connect(handle, &sa, size);
113 if(errno==EINPROGRESS)
116 set_events(IO::P_OUTPUT);
119 throw SystemError("Unable to connect", errno);
124 peer_addr=addr.copy();
127 size=sizeof(sockaddr);
128 getsockname(handle, &sa, &size);
129 local_addr=SockAddr::create(sa);
134 signal_connect_finished.emit(0);
141 Used by StreamListenSocket to construct a new socket from accept.
143 StreamSocket::StreamSocket(SocketHandle h, const SockAddr &paddr):
148 WSAEventSelect(handle, event, FD_READ|FD_CLOSE);
150 set_events(IO::P_INPUT);
153 void StreamSocket::on_event(IO::PollEvent ev)
155 //cout<<"StreamSocket::on_event "<<ev<<'\n';
156 if((ev&(IO::P_OUTPUT|IO::P_ERROR)) && connecting)
159 socklen_t len=sizeof(err);
160 get_option(SOL_SOCKET, SO_ERROR, &err, &len);
164 signal_connect_finished.emit(err);
173 WSAEventSelect(handle, event, FD_READ|FD_CLOSE);
175 set_events((err==0) ? IO::P_INPUT : IO::P_NONE);