artdaq_mfextensions  v1_03_02
TCP_listen_fd.hh
Go to the documentation of this file.
1 #ifndef TCP_listen_fd_hh
2 #define TCP_listen_fd_hh
3 
4 // This file (TCP_listen_fd.hh) was created by Ron Rechenmacher <ron@fnal.gov> on
5 // Sep 15, 2016. "TERMS AND CONDITIONS" governing this file are in the README
6 // or COPYING file. If you do not have such a file, one can be obtained by
7 // contacting Ron or Fermi Lab in Batavia IL, 60510, phone: 630-840-3000.
8 // $RCSfile: .emacs.gnu,v $
9 // rev="$Revision: 1.30 $$Date: 2016/03/01 14:27:27 $";
10 
11 
12 #include <stdio.h> // printf
13 #include <stdlib.h> // exit
14 #include <strings.h> // bzero
15 #include <sys/socket.h> /* inet_aton, socket, bind, listen, accept */
16 #include <netinet/in.h> /* inet_aton, struct sockaddr_in */
17 #include <arpa/inet.h> /* inet_aton */
18 #include <netdb.h> /* gethostbyname */
19 #include <errno.h> // errno
20 #include "trace.h"
21 
33 int TCP_listen_fd(int port, int rcvbuf)
34 {
35  int sts;
36  int listener_fd;
37  struct sockaddr_in sin;
38 
39  listener_fd = socket(PF_INET, SOCK_STREAM, 0); /* man TCP(7P) */
40  if (listener_fd == -1)
41  {
42  TLOG(TLVL_ERROR) << "Could not open listen socket! Exiting with code 1!";
43  perror("socket error");
44  exit(1);
45  }
46 
47  int opt = 1; // SO_REUSEADDR - man socket(7)
48  sts = setsockopt(listener_fd, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt));
49  if (sts == -1)
50  {
51  TLOG(TLVL_ERROR) << "Could not set SO_REUSEADDR! Exiting with code 2!";
52  perror("setsockopt SO_REUSEADDR");
53  return (2);
54  }
55 
56  bzero((char *)&sin, sizeof(sin));
57  sin.sin_family = AF_INET;
58  sin.sin_port = htons(port);
59  sin.sin_addr.s_addr = INADDR_ANY;
60 
61  //printf( "bind..." );fflush(stdout);
62  sts = bind(listener_fd, (struct sockaddr *)&sin, sizeof(sin));
63  if (sts == -1)
64  {
65  TLOG(TLVL_ERROR) << "Could not bind socket! Exiting with code 3!";
66  perror("bind error");
67  exit(3);
68  }
69  //printf( " OK\n" );
70 
71  int len = 0;
72  socklen_t arglen = sizeof(len);
73  sts = getsockopt(listener_fd, SOL_SOCKET, SO_RCVBUF, &len, &arglen);
74  TLOG(TLVL_WARNING) << "RCVBUF initial: " << len << " sts/errno=" << sts << "/" << errno << " arglen=" << arglen << " rcvbuf=" << rcvbuf << " listener_fd=" << listener_fd;
75  if (rcvbuf > 0)
76  {
77  len = rcvbuf;
78  sts = setsockopt(listener_fd, SOL_SOCKET, SO_RCVBUF, &len, arglen);
79  if (sts == -1)
80  TLOG(TLVL_ERROR) << "Error with setsockopt SNDBUF " << errno;
81  len = 0;
82  sts = getsockopt(listener_fd, SOL_SOCKET, SO_RCVBUF, &len, &arglen);
83  if (len < (rcvbuf * 2))
84  TLOG(TLVL_WARNING) << "RCVBUF " << len << " not expected (" << rcvbuf << " sts/errno=" << sts << "/" << errno;
85  else
86  TLOG(TLVL_DEBUG) << "RCVBUF " << len << " sts/errno=" << sts << "/" << errno;
87  }
88 
89  //printf( "listen..." );fflush(stdout);
90  sts = listen(listener_fd, 5/*QLEN*/);
91  if (sts == -1)
92  {
93  perror("listen error");
94  exit(1);
95  }
96  //printf( " OK\n" );
97 
98  return (listener_fd);
99 } // TCP_listen_fd
100 
101 #endif // TCP_listen_fd_hh
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...