artdaq  v3_09_01
TCP_listen_fd.cc
1 // This file (TCP_listen_fd.cpp) was created by Ron Rechenmacher <ron@fnal.gov> on
2 // Apr 20, 2010. "TERMS AND CONDITIONS" governing this file are in the README
3 // or COPYING file. If you do not have such a file, one can be obtained by
4 // contacting Ron or Fermi Lab in Batavia IL, 60510, phone: 630-840-3000.
5 // $RCSfile: TCP_listen_fd.cpp,v $
6 // rev="$Revision: 1.3 $$Date: 2010/06/04 14:00:32 $";
7 
8 #include "artdaq/DAQdata/Globals.hh"
9 #define TRACE_NAME (app_name + "_TCP_listen_fd").c_str()
10 
11 #include <arpa/inet.h> /* inet_aton */
12 #include <netdb.h> /* gethostbyname */
13 #include <netinet/in.h> /* inet_aton, struct sockaddr_in */
14 #include <strings.h> // bzero
15 #include <sys/socket.h> /* inet_aton, socket, bind, listen, accept */
16 #include <cerrno> // errno
17 #include <cstdio> // printf
18 #include <cstdlib> // exit
19 
21 
22 int TCP_listen_fd(int port, int rcvbuf)
23 {
24  int sts;
25  int listener_fd;
26  struct sockaddr_in sin;
27 
28  listener_fd = socket(PF_INET, SOCK_STREAM, 0); /* man TCP(7P) */
29  if (listener_fd == -1)
30  {
31  TLOG(TLVL_ERROR) << "Could not open listen socket! Exiting with code 1!";
32  perror("socket error");
33  exit(1);
34  }
35 
36  int opt = 1; // SO_REUSEADDR - man socket(7)
37  sts = setsockopt(listener_fd, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt));
38  if (sts == -1)
39  {
40  TLOG(TLVL_ERROR) << "Could not set SO_REUSEADDR! Exiting with code 2!";
41  perror("setsockopt SO_REUSEADDR");
42  return (2);
43  }
44 
45  memset(static_cast<void*>(&sin), 0, sizeof(sin));
46  sin.sin_family = AF_INET;
47  sin.sin_port = htons(port);
48  sin.sin_addr.s_addr = INADDR_ANY;
49 
50  //printf( "bind..." );fflush(stdout);
51  sts = bind(listener_fd, reinterpret_cast<struct sockaddr *>(&sin), sizeof(sin)); // NOLINT(cppcoreguidelines-pro-type-reinterpret-cast)
52  if (sts == -1)
53  {
54  TLOG(TLVL_ERROR) << "Could not bind socket for port " << port << "! Exiting with code 3!";
55  perror("bind error");
56  exit(3);
57  }
58  //printf( " OK\n" );
59 
60  int len = 0;
61  socklen_t arglen = sizeof(len);
62  sts = getsockopt(listener_fd, SOL_SOCKET, SO_RCVBUF, &len, &arglen);
63  TLOG(TLVL_INFO) << "RCVBUF initial: " << len << " sts/errno=" << sts << "/" << errno << " arglen=" << arglen << " rcvbuf=" << rcvbuf << " listener_fd=" << listener_fd;
64  if (rcvbuf > 0)
65  {
66  len = rcvbuf;
67  sts = setsockopt(listener_fd, SOL_SOCKET, SO_RCVBUF, &len, arglen);
68  if (sts == -1)
69  {
70  TLOG(TLVL_ERROR) << "Error with setsockopt SNDBUF " << errno;
71  }
72  len = 0;
73  sts = getsockopt(listener_fd, SOL_SOCKET, SO_RCVBUF, &len, &arglen);
74  if (len < (rcvbuf * 2))
75  {
76  TLOG(TLVL_WARNING) << "RCVBUF " << len << " not expected (" << rcvbuf << " sts/errno=" << sts << "/" << errno;
77  }
78  else
79  {
80  TLOG(TLVL_DEBUG) << "RCVBUF " << len << " sts/errno=" << sts << "/" << errno;
81  }
82  }
83 
84  //printf( "listen..." );fflush(stdout);
85  sts = listen(listener_fd, 5 /*QLEN*/);
86  if (sts == -1)
87  {
88  TLOG(TLVL_ERROR) << "Error calling listen! errno=" << errno << " (" << strerror(errno) << ")";
89  perror("listen error");
90  exit(1);
91  }
92  //printf( " OK\n" );
93 
94  return (listener_fd);
95 } // TCP_listen_fd
int TCP_listen_fd(int port, int rcvbuf)
Create a TCP listening socket on the given port and INADDR_ANY, with the given receive buffer...