62 #define SOCKET_ERROR (-1)
78 #define TCP_SELECT_BEFORE_ACCEPT 0
79 #define TCP_SELECT_BEFORE_READ 0
80 #define TCP_SELECT_BEFORE_WRITE 0
82 #if defined _MSC_VER && defined min
85 #if defined _MSC_VER && defined max
114 memset(&tSockAddr,0,
sizeof(tSockAddr));
121 m_tListenSocket = ::socket( PF_INET, SOCK_STREAM, IPPROTO_TCP );
124 ROS_ERROR_STREAM(
"## ERROR ServerSocket::open(" << m_iListenPortNumber <<
"," << bTcpAnyHost <<
"): can't open socket");
128 tSockAddr.sin_family = AF_INET;
129 tSockAddr.sin_port = htons((
unsigned short)m_iListenPortNumber);
132 tSockAddr.sin_addr.s_addr = htonl(INADDR_ANY);
136 tSockAddr.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
140 bOkay = bOkay && (setsockopt(m_tListenSocket,SOL_SOCKET,SO_REUSEADDR,(
const char*)&reuseaddr,
sizeof(reuseaddr)) !=
SOCKET_ERROR);
141 bOkay = bOkay && (bind(m_tListenSocket, (
SOCKADDR*)&tSockAddr,
sizeof(tSockAddr)) == 0);
142 bOkay = bOkay && (listen(m_tListenSocket, 1) == 0);
146 ROS_ERROR_STREAM(
"## ERROR ServerSocket::open(" << m_iListenPortNumber <<
"," << bTcpAnyHost <<
"): bind socket resp. listen failed.");
151 ROS_INFO_STREAM(
"ServerSocket: listening to port " << m_iListenPortNumber);
164 ROS_ERROR_STREAM(
"## ERROR ServerSocket::connect(port " << m_iListenPortNumber <<
"): socket not initialized, call open() before connect().");
169 # if UTL_TCP_SELECT_BEFORE_ACCEPT
173 FD_SET(m_tListenSocket, &readfds);
174 if (select(0, &readfds,
NULL,
NULL,
NULL) <= 0 || FD_ISSET(m_tListenSocket, &readfds) == 0)
176 ROS_ERROR_STREAM(
"## ERROR ServerSocket::connect(port " << m_iListenPortNumber <<
"): select failed.");
180 # endif // TCP_SELECT_BEFORE_ACCEPT
182 m_tConnectedSocket = accept(m_tListenSocket,
NULL,
NULL);
185 ROS_ERROR_STREAM(
"## ERROR ServerSocket::connect(port " << m_iListenPortNumber <<
"): accept failed.");
189 ROS_INFO_STREAM(
"ServerSocket (port " << m_iListenPortNumber <<
"): connected to client.");
201 ROS_ERROR_STREAM(
"## ERROR ServerSocket::read(port " << m_iListenPortNumber <<
"): socket not connected");
209 # if TCP_SELECT_BEFORE_READ
213 FD_SET(m_tConnectedSocket, &readfds);
214 if (select(0, &readfds,
NULL,
NULL,
NULL) <= 0 || FD_ISSET(m_tConnectedSocket, &readfds ) == 0)
216 ROS_ERROR_STREAM(
"## ERROR ServerSocket::read(port " << m_iListenPortNumber <<
"): select failed.");
225 u_long recv_mode = (read_blocking ? 0 : 1);
226 ioctlsocket(m_tConnectedSocket, FIONBIO, &recv_mode);
229 recv_flags |= MSG_DONTWAIT;
232 std::vector<uint8_t> buffer(num_bytes);
236 int n = ::recv(m_tConnectedSocket, (
char*)(buffer.data() + nrbytes), num_bytes - nrbytes, recv_flags);
241 std::this_thread::sleep_for(std::chrono::milliseconds(1));
251 out_buffer.insert(out_buffer.end(), buffer.begin(), buffer.end());
253 if (read_blocking && nrbytes < num_bytes)
255 ROS_ERROR_STREAM(
"## ERROR ServerSocket::read(port " << m_iListenPortNumber <<
"): failed, " << nrbytes <<
" of " << num_bytes <<
" bytes read from socket.");
266 std::vector<uint8_t> buffer;
267 int nrbytes =
read(num_bytes, buffer, read_blocking);
269 memcpy(out_buffer, buffer.data(), std::min(nrbytes, num_bytes));
270 return nrbytes == num_bytes;
282 ROS_ERROR_STREAM(
"## ERROR ServerSocket::write(port " << m_iListenPortNumber <<
"): socket not connected");
285 if (buffer ==
NULL || num_bytes <= 0)
290 int nrbytes = 0, nrErrors = 0;
291 num_retries_on_error = std::max(num_retries_on_error, 1);
294 # if TCP_SELECT_BEFORE_WRITE
296 FD_ZERO( &writefds );
297 FD_SET( m_tConnectedSocket, &writefds );
298 if (select( 0,
NULL, &writefds,
NULL,
NULL) <= 0 || FD_ISSET( ptServerSocket->tConnectedSocket, &writefds ) == 0)
300 ROS_ERROR_STREAM(
"## ERROR ServerSocket::write(port " << m_iListenPortNumber <<
"): select failed.");
304 nrbytes = send(m_tConnectedSocket, (
char*)buffer, num_bytes, 0);
307 num_bytes -= nrbytes;
316 ROS_ERROR_STREAM(
"## ERROR ServerSocket::write(port " << m_iListenPortNumber <<
"): failed to send " << num_bytes <<
" bytes.");