tcp_server.cpp
Go to the documentation of this file.
1 /*
2  * Software License Agreement (BSD License)
3  *
4  * Copyright (c) 2011, Southwest Research Institute
5  * All rights reserved.
6  *
7  * Redistribution and use in source and binary forms, with or without
8  * modification, are permitted provided that the following conditions are met:
9  *
10  * * Redistributions of source code must retain the above copyright
11  * notice, this list of conditions and the following disclaimer.
12  * * Redistributions in binary form must reproduce the above copyright
13  * notice, this list of conditions and the following disclaimer in the
14  * documentation and/or other materials provided with the distribution.
15  * * Neither the name of the Southwest Research Institute, nor the names
16  * of its contributors may be used to endorse or promote products derived
17  * from this software without specific prior written permission.
18  *
19  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
20  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
23  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29  * POSSIBILITY OF SUCH DAMAGE.
30  */
31 #ifndef FLATHEADERS
34 #else
35 #include "tcp_server.h"
36 #include "log_wrapper.h"
37 #endif
38 
39 namespace industrial
40 {
41 namespace tcp_server
42 {
43 
45 {
46  this->setSockHandle(this->SOCKET_FAIL);
47  this->setSrvrHandle(this->SOCKET_FAIL);
48  memset(&this->sockaddr_, 0, sizeof(this->sockaddr_));
49 }
50 
52 {
53  CLOSE(this->getSockHandle());
54  CLOSE(this->getSrvrHandle());
55 }
56 
57 bool TcpServer::init(int port_num)
58 {
59  int rc;
60  bool rtn;
61  const int reuse_addr = 1;
62  //int err;
63  SOCKLEN_T addrSize = 0;
64 
65  rc = SOCKET(AF_INET, SOCK_STREAM, 0);
66  if (this->SOCKET_FAIL != rc)
67  {
68  this->setSrvrHandle(rc);
69  LOG_DEBUG("Socket created, rc: %d", rc);
70  LOG_DEBUG("Socket handle: %d", this->getSrvrHandle());
71 
72 
73  SET_REUSE_ADDR(this->getSrvrHandle(), reuse_addr);
74 
75  // Initialize address data structure
76  memset(&this->sockaddr_, 0, sizeof(this->sockaddr_));
77  this->sockaddr_.sin_family = AF_INET;
78  this->sockaddr_.sin_addr.s_addr = INADDR_ANY;
79  this->sockaddr_.sin_port = HTONS(port_num);
80 
81  addrSize = sizeof(this->sockaddr_);
82  rc = BIND(this->getSrvrHandle(), (sockaddr *)&(this->sockaddr_), addrSize);
83 
84  if (this->SOCKET_FAIL != rc)
85  {
86  LOG_INFO("Server socket successfully initialized");
87 
88  rc = LISTEN(this->getSrvrHandle(), 1);
89 
90  if (this->SOCKET_FAIL != rc)
91  {
92  LOG_INFO("Socket in listen mode");
93  rtn = true;
94  }
95  else
96  {
97  LOG_ERROR("Failed to set socket to listen");
98  rtn = false;
99  }
100  }
101  else
102  {
103  LOG_ERROR("Failed to bind socket, rc: %d", rc);
104  CLOSE(this->getSrvrHandle());
105  rtn = false;
106  }
107 
108  }
109  else
110  {
111  LOG_ERROR("Failed to create socket, rc: %d", rc);
112  rtn = false;
113  }
114 
115  return rtn;
116 }
117 
119 {
120  bool rtn = false;
121  int rc = this->SOCKET_FAIL;
122  //int socket = this->SOCKET_FAIL;
123  int disableNodeDelay = 1;
124  int err = 0;
125 
126  if (!this->isConnected())
127  {
128  this->setConnected(false);
129  if (this->SOCKET_FAIL != this->getSockHandle())
130  {
131  CLOSE(this->getSockHandle());
132  this->setSockHandle(this->SOCKET_FAIL);
133  }
134 
135  rc = ACCEPT(this->getSrvrHandle(), NULL, NULL);
136 
137  if (this->SOCKET_FAIL != rc)
138  {
139  this->setSockHandle(rc);
140  LOG_INFO("Client socket accepted");
141 
142  // The set no delay disables the NAGEL algorithm
143  rc = SET_NO_DELAY(this->getSockHandle(), disableNodeDelay);
144  err = errno;
145  if (this->SOCKET_FAIL == rc)
146  {
147  LOG_WARN("Failed to set no socket delay, errno: %d, sending data can be delayed by up to 250ms", err);
148  }
149  this->setConnected(true);
150  rtn = true;
151  }
152  else
153  {
154  LOG_ERROR("Failed to accept for client connection");
155  rtn = false;
156  }
157  }
158  else
159  {
160  LOG_WARN("Tried to connect when socket already in connected state");
161  }
162 
163  return rtn;
164 
165 }
166 
167 } //tcp_socket
168 } //industrial
169 
virtual void setConnected(bool connected)
#define LOG_WARN(format,...)
Definition: log_wrapper.h:133
#define LOG_ERROR(format,...)
Definition: log_wrapper.h:134
sockaddr_in sockaddr_
address/port of remote socket
#define LOG_INFO(format,...)
Definition: log_wrapper.h:132
bool makeConnect()
connects to the remote host
Definition: tcp_server.cpp:118
#define LOG_DEBUG(format,...)
Definition: log_wrapper.h:131
bool isConnected()
return connection status
void setSrvrHandle(int srvr_handle_)
Definition: tcp_server.h:89
static const int SOCKET_FAIL
socket fail return value
bool init(int port_num)
initializes TCP server socket. The connect method must be called following initialization in order to...
Definition: tcp_server.cpp:57


simple_message
Author(s): Shaun Edwards
autogenerated on Mon Jul 19 2021 12:45:19