otsdaq-mu2e-stm  5.02.01
UDPsocket_old.cc
1 // This module creates a UDP socket for 10G readout (main).
4 
5 /********************************************************************/
6 
7 // Environment variables
8 //#include "STMDAQ-/utils/EnvVars.hh"
9 
10 // UDP socket header
11 //#include "STMDAQ-TestBeam/utils/UDPsocket.hh"
12 #include "UDPsocket.hh"
13 
14 // Hex reader
15 //#include "STMDAQ-TestBeam/utils/Hex.hh"
16 
17 #include <fstream>
18 #include <iostream>
19 #include <vector>
20 
21 #include <arpa/inet.h>
22 #include <string.h> //memset
23 #include <sys/socket.h>
24 #include <sys/types.h>
25 
26 #include <time.h>
27 
28 #include <fcntl.h> // for open
29 #include <unistd.h> // for close
30 
31 using namespace std;
32 
33 int recv_len;
34 int ret[2];
35 struct timeval read_timeout;
36 
37 /*-- UDP Socket Init -------------------------------------------------*/
38 
39 //Standard constructor - shouldn't be used
41 
42 // const char* UDPsocket::getIPaddress(int READWRITE){
43 
44 // const char* ip_address;
45 
46 // // Get UDP IP address from environment varaibles
47 // string ip;
48 // // If reading data...
49 // if (READWRITE == READ){
50 // ip = EnvVars::expand("${STM_READ_IP}");
51 // }
52 // // If writing data...
53 // else if (READWRITE == WRITE){
54 // ip = EnvVars::expand("${STM_WRITE_IP}");
55 // }
56 // // Else if read/write is not 0 or 1...
57 // else{
58 // cout << "Error! In UDPsocket::getIPaddress, READWRITE = " << READWRITE << endl;
59 // cout << "\tREADWRITE must equal 0 or 1. Exting...\n" << endl;
60 // exit(0);
61 // }
62 // ip_address = ip.c_str();
63 // cout << "IP ADDRESSS IS: " << ip_address << endl;
64 
65 // return ip_address;
66 
67 // }
68 
69 // int UDPsocket::getPort(int READWRITE){
70 
71 // // Get UDP port number from environment variables
72 // string portNum;
73 // // If reading data...
74 // if (READWRITE == READ){
75 // portNum = EnvVars::expand("${STM_READ_PORT}");
76 // }
77 // // If writing data...
78 // else if (READWRITE == WRITE){
79 // portNum = EnvVars::expand("${STM_WRITE_PORT}");
80 // }
81 // // Else if read/write is not 0 or 1...
82 // else{
83 // cout << "Error! In UDPsocket::getPort, READWRITE = " << READWRITE << endl;
84 // cout << "\tREADWRITE must equal 0 or 1. Exting...\n" << endl;
85 // exit(0);
86 // }
87 
88 // const int port = stoi(portNum);
89 
90 // return port;
91 
92 // }
93 
94 int UDPsocket::createSocket(int CHANNEL)
95 {
96  int sock;
97 
98  // Creating socket file descriptor
99  sock = socket(AF_INET, SOCK_DGRAM, 0);
100  if((sock = socket(AF_INET, SOCK_DGRAM, 0)) == -1)
101  { //IPPROTO_UDP
102  die((char*)"socket");
103  }
104 
105  close(sock);
106 
107  // Creating socket file descriptor
108  sock = socket(AF_INET, SOCK_DGRAM, 0);
109  if((sock = socket(AF_INET, SOCK_DGRAM, 0)) == -1)
110  { //IPPROTO_UDP
111  die((char*)"socket");
112  }
113 
114  // zero out the structure
115  memset((char*)&servaddr, 0, sizeof(servaddr));
116 
117  // Filling server information
118  servaddr.sin_family = AF_INET;
119  // servaddr.sin_port = htons(getPort(READWRITE));
120  servaddr.sin_port = htons(getPORT(CHANNEL));
121  // servaddr.sin_addr.s_addr = inet_addr(getIPaddress(READWRITE));
122  servaddr.sin_addr.s_addr = inet_addr(getIPaddress(CHANNEL));
123 
124  cout << "SERVER: Channel = " << CHANNEL << ": IP = " << getIPaddress(CHANNEL)
125  << ", PORT = " << getPORT(CHANNEL) << ", socket = " << sock << endl;
126 
127  // Set socket to allow port re-use / to reuse port
128  int optval = 1;
129  setsockopt(sock, SOL_SOCKET, SO_REUSEPORT, &optval, sizeof(optval));
130 
131  return sock;
132 }
133 
134 // int UDPsocket::closeSocket(int sock){
135 
136 // return sock;
137 
138 // }
139 
140 int UDPsocket::createClient(int CHANNEL)
141 {
142  int sock;
143 
144  // Creating UDP socket file descriptor
145  if((sock = socket(AF_INET, SOCK_DGRAM, 0)) < 0)
146  {
147  perror("socket creation failed");
148  exit(EXIT_FAILURE);
149  }
150 
151  // Zero UDP server address structure
152  memset(&servaddr, 0, sizeof(servaddr));
153 
154  // Fill UDP server information
155  servaddr.sin_family = AF_INET;
156  // servaddr.sin_port = htons(getPort(READWRITE));
157  servaddr.sin_port = htons(getPORT(CHANNEL));
158  // servaddr.sin_addr.s_addr = inet_addr(getIPaddress(READWRITE));
159  servaddr.sin_addr.s_addr = inet_addr(getIPaddress(CHANNEL));
160 
161  cout << "CLIENT: Channel = " << CHANNEL << ": IP = " << getIPaddress(CHANNEL)
162  << ", PORT = " << getPORT(CHANNEL) << ", socket = " << sock << endl;
163 
164  return sock;
165 }
166 
167 // Bind socket to port
168 int UDPsocket::bindSocket(int socket)
169 {
170  if(bind(socket, (struct sockaddr*)&servaddr, sizeof(servaddr)) == -1)
171  {
172  die((char*)"bind");
173  }
174 
175  // Zero out the client address structure
176  memset((char*)&cliaddr, 0, sizeof(cliaddr));
177 
178  fflush(stdout);
179 
180  return socket;
181 }
182 
183 // Set SO_RCVBUF size
184 int UDPsocket::set_SO_RCVBUF(int socket, uint32_t size)
185 {
186  int bufferSize =
187  setsockopt(socket, SOL_SOCKET, SO_RCVBUF, (char*)&size, sizeof(size));
188  return bufferSize;
189 }
190 
191 // Set SO_SNDBUF size
192 int UDPsocket::set_SO_SNDBUF(int socket, uint32_t size)
193 {
194  int bufferSize =
195  setsockopt(socket, SOL_SOCKET, SO_SNDBUF, (char*)&size, sizeof(size));
196  return bufferSize;
197 }
198 
199 // Set recvfrom non-blocking timeout
200 int UDPsocket::setTimeout(int secs, double usecs)
201 {
202  read_timeout.tv_sec = secs;
203  read_timeout.tv_usec = usecs;
204 
205  return 1;
206 }
207 
208 // Send packet to socket
209 int UDPsocket::sendPacket(struct packet& p, int socket)
210 {
211  sendto(socket,
212  p.data,
213  p.size,
214  MSG_CONFIRM,
215  (const struct sockaddr*)&servaddr,
216  sizeof(servaddr));
217 
218  return 1;
219 }
220 
221 // Request packet from socket and return as vector of 16-bit words
222 int UDPsocket::getPacket(packet& p, int socket, int chan)
223 {
224  FD_ZERO(&readfds);
225  FD_SET(socket, &readfds);
226  ret[chan] = select(socket + 1, &readfds, NULL, NULL, &read_timeout);
227  if(ret[chan] > 0)
228  {
229  // socket has pending data to read
230  if((p.size = recvfrom(socket,
231  p.data,
232  rcvbufsize,
233  0,
234  (struct sockaddr*)&cliaddr,
235  (socklen_t*)&slen)) < 0)
236  {
237  die((char*)"recvfrom()");
238  }
239  }
240  else if(ret[chan] == 0)
241  {
242  return 0;
243  // todo: resend the same packet again, or abort the transfer
244  }
245  else
246  {
247  cout << "error selecting: ret = " << ret[chan] << endl;
248  }
249 
250  return 1;
251 }
252 
253 // Flush queueds packet from socket and return 0 when no bytes left to receive
254 int UDPsocket::flushPackets(int socket)
255 {
256  uint16_t length = getBufferLength();
257  buffer = new int16_t[length];
258  int recv_len = 1;
259 
260  // Zero out the client address structure
261  memset((char*)&cliaddr, 0, sizeof(cliaddr));
262 
263  fflush(stdout);
264 
265  cout << "Flushing previous packets..." << endl;
266 
267  while(1)
268  {
269  if((recv_len = recvfrom(socket,
270  buffer,
271  rcvbufsize,
272  MSG_DONTWAIT,
273  (struct sockaddr*)&cliaddr,
274  (socklen_t*)&slen)) == -1)
275  {
276  cout << "No packets in queue!" << endl;
277  break;
278  }
279  else
280  {
281  cout << "Flushed packet with size " << recv_len << " bytes." << endl;
282  }
283  }
284 
285  return recv_len;
286 }
UDPsocket()
This module creates a UDP socket for 10G readout (main).
Definition: UDPsocket.cc:40
Definition: queue.hh:10