artdaq_mfextensions  v1_03_05
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 #include <arpa/inet.h> /* inet_aton */
12 #include <errno.h> // errno
13 #include <netdb.h> /* gethostbyname */
14 #include <netinet/in.h> /* inet_aton, struct sockaddr_in */
15 #include <stdio.h> // printf
16 #include <stdlib.h> // exit
17 #include <strings.h> // bzero
18 #include <sys/socket.h> /* inet_aton, socket, bind, listen, accept */
19 #include "trace.h"
20 
32 int TCP_listen_fd(int port, int rcvbuf) {
33  int sts;
34  int listener_fd;
35  struct sockaddr_in sin;
36 
37  listener_fd = socket(PF_INET, SOCK_STREAM, 0); /* man TCP(7P) */
38  if (listener_fd == -1) {
39  TLOG(TLVL_ERROR) << "Could not open listen socket! Exiting with code 1!";
40  perror("socket error");
41  exit(1);
42  }
43 
44  int opt = 1; // SO_REUSEADDR - man socket(7)
45  sts = setsockopt(listener_fd, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt));
46  if (sts == -1) {
47  TLOG(TLVL_ERROR) << "Could not set SO_REUSEADDR! Exiting with code 2!";
48  perror("setsockopt SO_REUSEADDR");
49  return (2);
50  }
51 
52  bzero((char *)&sin, sizeof(sin));
53  sin.sin_family = AF_INET;
54  sin.sin_port = htons(port);
55  sin.sin_addr.s_addr = INADDR_ANY;
56 
57  // printf( "bind..." );fflush(stdout);
58  sts = bind(listener_fd, (struct sockaddr *)&sin, sizeof(sin));
59  if (sts == -1) {
60  TLOG(TLVL_ERROR) << "Could not bind socket! Exiting with code 3!";
61  perror("bind error");
62  exit(3);
63  }
64  // printf( " OK\n" );
65 
66  int len = 0;
67  socklen_t arglen = sizeof(len);
68  sts = getsockopt(listener_fd, SOL_SOCKET, SO_RCVBUF, &len, &arglen);
69  TLOG(TLVL_WARNING) << "RCVBUF initial: " << len << " sts/errno=" << sts << "/" << errno << " arglen=" << arglen
70  << " rcvbuf=" << rcvbuf << " listener_fd=" << listener_fd;
71  if (rcvbuf > 0) {
72  len = rcvbuf;
73  sts = setsockopt(listener_fd, SOL_SOCKET, SO_RCVBUF, &len, arglen);
74  if (sts == -1) TLOG(TLVL_ERROR) << "Error with setsockopt SNDBUF " << errno;
75  len = 0;
76  sts = getsockopt(listener_fd, SOL_SOCKET, SO_RCVBUF, &len, &arglen);
77  if (len < (rcvbuf * 2))
78  TLOG(TLVL_WARNING) << "RCVBUF " << len << " not expected (" << rcvbuf << " sts/errno=" << sts << "/" << errno;
79  else
80  TLOG(TLVL_DEBUG) << "RCVBUF " << len << " sts/errno=" << sts << "/" << errno;
81  }
82 
83  // printf( "listen..." );fflush(stdout);
84  sts = listen(listener_fd, 5 /*QLEN*/);
85  if (sts == -1) {
86  perror("listen error");
87  exit(1);
88  }
89  // printf( " OK\n" );
90 
91  return (listener_fd);
92 } // TCP_listen_fd
93 
94 #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...