otsdaq-mu2e-stm  5.02.01
client_multiple.cc
1 
5 /********************************************************************/
6 
7 #include <fstream>
8 #include <iostream>
9 #include <vector>
10 
11 #include <arpa/inet.h>
12 #include <string.h> //memset
13 #include <sys/socket.h>
14 #include <sys/types.h>
15 
16 #include <fcntl.h> // for open
17 #include <unistd.h> // for close
18 
19 #include <math.h> /* pow */
20 
21 #include <thread>
22 
23 using namespace std;
24 
25 static const uint16_t maxGbit = 10; // Gbits
26 static const double maxbytes = maxGbit * 1e9 * 0.125; // bytes
27 
28 static const uint16_t packetSize = 8198; // bytes
29 static const uint16_t BUFLEN = packetSize / 2;
30 
31 //static const uint packetNum = int(maxbytes)/packetSize;
32 static const uint packetNum = int(2e9) / packetSize;
33 //static const uint packetNum = 1e6;
34 
35 static const uint chNum = 2;
36 
37 //static const char* IP[chNum] = {"127.0.0.1","127.0.0.2"};
38 static const char* IP[chNum] = {"192.168.34.12", "192.168.34.14"};
39 static const int PORT[chNum] = {51872, 51874};
40 
41 int client[chNum] = {};
42 
43 uint packetCount[chNum] = {};
44 
45 struct packet
46 {
47  uint size = 2 * BUFLEN;
48  int16_t data[BUFLEN] = {};
49 };
50 
51 // Initialise data packet and number of packets
52 packet* dataPacket[chNum];
53 
54 struct sockaddr_in servaddr[chNum], cliaddr[chNum];
55 
56 int slen = sizeof(cliaddr);
57 
58 void die(char* s)
59 {
60  perror(s);
61  exit(1);
62 }
63 
64 int createClient(uint chan)
65 {
66  int sock;
67 
68  // Creating UDP socket file descriptor
69  if((sock = socket(AF_INET, SOCK_DGRAM, 0)) < 0)
70  {
71  perror("socket creation failed");
72  exit(EXIT_FAILURE);
73  }
74 
75  // Zero UDP server address structure
76  memset(&servaddr[chan], 0, sizeof(servaddr[chan]));
77 
78  // Fill UDP server information
79  servaddr[chan].sin_family = AF_INET;
80  servaddr[chan].sin_port = htons(PORT[chan]);
81  servaddr[chan].sin_addr.s_addr = inet_addr(IP[chan]);
82 
83  cout << "Channel = " << chan << ": IP = " << IP[chan] << ", PORT = " << PORT[chan]
84  << ", socket = " << sock << endl;
85 
86  static const uint32_t sndbufsize = pow(2, 21);
87  setsockopt(sock, SOL_SOCKET, SO_SNDBUF, (char*)&sndbufsize, sizeof(sndbufsize));
88 
89  return sock;
90 }
91 
92 // Send packets to socket
93 int sendPacket(uint chan, int socket, packet* p)
94 {
95  // Loop over packets to send
96  for(uint i = 0; i < packetNum; i++)
97  {
98  // Sleep
99  // usleep(1);
100 
101  // Send packet
102  sendto(socket,
103  p[i].data,
104  p[i].size,
105  MSG_CONFIRM,
106  (const struct sockaddr*)&servaddr[chan],
107  sizeof(servaddr[chan]));
108 
109  // Increment sent packet counter
110  packetCount[chan]++;
111  }
112 
113  return 1;
114 }
115 
116 int main()
117 {
118  cout << "Creating distinct packets..." << endl;
119 
120  // Loop over packets to send
121  dataPacket[0] = new packet[packetNum];
122  dataPacket[1] = new packet[packetNum];
123  for(uint j = 0; j < packetNum; j++)
124  {
125  for(uint k = 0; k < BUFLEN; k++)
126  {
127  dataPacket[0][j].data[k] = j + k;
128  dataPacket[1][j].data[k] = 1 + j + k;
129  }
130  }
131 
132  for(int i = 0; i < 5; i++)
133  {
134  cout << "Sending packets in " << 5 - i << "..." << endl;
135  sleep(1);
136  }
137 
138  // Loop over channels
139  // Create client for each channel
140  for(uint i = 0; i < chNum; i++)
141  {
142  client[i] = createClient(i);
143  }
144 
145  // Create client thread for each channels
146  std::thread* client_thread[chNum];
147 
148  // Execute client thread for each channel
149  for(uint i = 0; i < chNum; i++)
150  {
151  client_thread[i] = new std::thread(sendPacket, i, client[i], dataPacket[i]);
152  }
153 
154  // Join client threads
155  for(uint i = 0; i < chNum; i++)
156  {
157  client_thread[i]->join();
158  cout << "Channel " << i << " sent " << packetCount[i] << " packets" << endl;
159  }
160 
161  return 1;
162 }
Definition: data.hh:4
Definition: queue.hh:10