diff C++/SocketTcp.cpp @ 316:4c0af1143fc4

Add wait operation (no tests yet)
author David Demelier <markand@malikania.fr>
date Tue, 03 Mar 2015 18:48:54 +0100
parents c9356cb38c86
children 890729b8cb60
line wrap: on
line diff
--- a/C++/SocketTcp.cpp	Mon Mar 02 14:00:48 2015 +0100
+++ b/C++/SocketTcp.cpp	Tue Mar 03 18:48:54 2015 +0100
@@ -17,6 +17,7 @@
  */
 
 #include "SocketAddress.h"
+#include "SocketListener.h"
 #include "SocketTcp.h"
 
 /* --------------------------------------------------------
@@ -73,6 +74,9 @@
 
 void SocketTcp::connect(const SocketAddress &address)
 {
+	if (m_state == SocketState::Connected)
+		return;
+
 	auto &sa = address.address();
 	auto addrlen = address.length();
 
@@ -93,6 +97,50 @@
 		throw SocketError("connect", Socket::syserror(), errno);
 #endif
 	}
+
+	m_state = SocketState::Connected;
+}
+
+void SocketTcp::waitConnect(const SocketAddress &address, int timeout)
+{
+	if (m_state == SocketState::Connected)
+		return;
+
+	// Initial try
+	try {
+		connect(address);
+	} catch (const SocketError &ex) {
+		// TODO: HANDLE ERROR CODE
+
+		SocketListener listener{{*this, SocketListener::Write}};
+
+		listener.select(timeout);
+
+		// Socket is writable? Check if there is an error
+		int error = get<int>(SOL_SOCKET, SO_ERROR);
+
+		if (error) {
+			throw SocketError("connect", Socket::syserror(error), error);
+		}
+	}
+
+	m_state = SocketState::Connected;
+}
+
+SocketTcp SocketTcp::waitAccept(int timeout)
+{
+	SocketAddress dummy;
+
+	return waitAccept(dummy, timeout);
+}
+
+SocketTcp SocketTcp::waitAccept(SocketAddress &info, int timeout)
+{
+	SocketListener listener{{*this, SocketListener::Read}};
+
+	listener.select(timeout);
+
+	return accept(info);
 }
 
 unsigned SocketTcp::recv(void *data, unsigned dataLen)
@@ -112,11 +160,21 @@
 
 		throw SocketError("recv", Socket::syserror(), errno);
 #endif
-	}
+	} else if (nbread == 0)
+		m_state = SocketState::Closed;
 
 	return (unsigned)nbread;
 }
 
+unsigned SocketTcp::waitRecv(void *data, unsigned length, int timeout)
+{
+	SocketListener listener{{*this, SocketListener::Read}};
+
+	listener.select(timeout);
+
+	return recv(data, length);
+}
+
 unsigned SocketTcp::send(const void *data, unsigned length)
 {
 	int nbsent;
@@ -138,3 +196,12 @@
 
 	return (unsigned)nbsent;
 }
+
+unsigned SocketTcp::waitSend(const void *data, unsigned length, int timeout)
+{
+	SocketListener listener{{*this, SocketListener::Write}};
+
+	listener.select(timeout);
+
+	return send(data, length);
+}