source: tools/FAD/SocketFunctions/SocketFunctions.cpp@ 580

Last change on this file since 580 was 256, checked in by dneise, 14 years ago
simple daq now opens outfiles in path given in config.txt
File size: 6.6 KB
Line 
1#include <sys/socket.h>
2#include <arpa/inet.h>
3#include <cstdlib>
4#include <time.h>
5#include <sys/time.h>
6#include <sys/types.h>
7#include <unistd.h>
8#include <stdio.h>
9
10#include "SocketFunctions.h"
11
12/*
13OpenSockets opens NumberOfSockets TCP Sockets.
14a pointer to an array of SocketDescriptors is returned.
15In case of error, the NULL pointer is returned.
16
17In order to Close the Sockets and free memory call
18void CloseSockets(int * SocketDescriptors, unsigned int NumberOfSockets);
19*/
20
21int * OpenSockets(unsigned int NumberOfSockets){
22int verbose=0;
23
24if (verbose)
25
26 if (NumberOfSockets < 1) {
27 fprintf ( stderr,
28 "Error: OpenSockets was called with a NumberOfSockets = %d.\n",
29 NumberOfSockets );
30 return NULL;
31 }
32 if (NumberOfSockets > MAX_NUMBER_OF_OPENED_TCP_SOCKETS) {
33 fprintf ( stderr,
34 "Warning: OpenSockets was called with a NumberOfSockets = %d.\n",
35 NumberOfSockets );
36 return NULL;
37 }
38
39 int *SocketDescriptor;
40 if (verbose) fprintf (stderr, "malloc\n");
41 SocketDescriptor = (int *) malloc( NumberOfSockets * sizeof(int) );
42 if (verbose) fprintf (stderr, "after malloc\n");
43 // what if malloc was not able to get enough memory?
44 // error chekc missing here
45 // TODO
46
47 for (unsigned int i = 0; i < NumberOfSockets; i++) {
48 if ((SocketDescriptor[i] = socket (PF_INET, SOCK_STREAM, 0)) == -1) {
49 //
50 // what does PF_INET and SOCK_STREAM stand for?
51 //
52 printf ("Error: Could not open socket Nr.: %d\n", i);
53 return NULL;
54 }
55 }
56 return SocketDescriptor;
57 if (verbose) printf ("end of OpenSockets\n");
58} // end of OpenSockets
59
60
61
62
63
64 /*
65 EmptySockets is used to read as much data from the TCP-Sockets in question
66 as possible. After waiting "timeout_usec" (default 125ms) -- see header file
67 without any data beeing present, the Socket is assumed to be empty.
68
69 Hopefully it is.
70
71 return is true if there was no error during the select statement.
72 false if select returned <0, which should not happen at all.
73 What to do if this happened?
74 */
75
76
77bool EmptySockets(int * SocketDescriptor, int NumberOfDescriptors, long timeout_usec){
78
79 fd_set Sockets; // select looks into this set, and checks which Sockets state changed
80 timeval timeout; // select needs a timeout to be deifned.
81 int max_fd=0; // select needs to know the maximum descriptor in fd_set Sockets.
82 int select_return; // used for debugging
83
84 unsigned char wastebin[WASTEBIN_SIZE]; // data ffrom sockets is dumped here
85
86 // find the maximum of SocketDescriptors
87 // needed by select() -- see man select
88
89
90 FD_ZERO (&Sockets);
91 for (int j = 0; j < NumberOfDescriptors; j++)
92 {
93 if (max_fd<SocketDescriptor[j]) {
94 max_fd = SocketDescriptor[j];
95 }
96 FD_SET (SocketDescriptor[j], &Sockets);
97 }
98 max_fd ++;
99
100 while (1){
101 timeout.tv_sec = 0;
102 timeout.tv_usec = timeout_usec;
103 select_return = select ( max_fd, &Sockets, NULL, NULL, &timeout);
104 if (select_return == 0) {
105 // none of the Sockets status changed
106 // nothing to read
107 break;
108 } else if (select_return <=0) {
109 return false; // this should never happen
110 fprintf(stderr, "error in EmptySockets: select returned %d abort. \n" , select_return);
111 } else { // select returned > 0
112 // now some Sockets might contain data
113 // it is checked for every Socket using: FD_ISSET
114 // then a pieces of WASTEBIN_SIZE chars is read out and discarded.
115 for (int j = 0; j < NumberOfDescriptors; j++) {
116 if (FD_ISSET (SocketDescriptor[j], &Sockets)){
117 read(SocketDescriptor[j], wastebin, WASTEBIN_SIZE);
118 }
119 }
120 //now every Socket, which had still some bytes, lost WASTEBIN_SIZE of it.
121 // still some might contain data -- so select is executed again.
122 }// end of else case: select returned > 0
123 } // end of while(1) loop -- jumped out if select returns 0
124return true;
125}
126
127/*
128 GetMaxFileDescriptor returns the value of the maximal
129 filedescriptor from NumberOfSockets SocketDescriptors.
130 The maximal filedescriptor + 1 is needed for select().
131*/
132
133int GetMaxFileDescriptor(unsigned int NumberOfSockets, int *SocketDescriptor){
134 int max_fd;
135 for (unsigned int i = 0; i < NumberOfSockets; i++)
136 {
137 if (SocketDescriptor[i] > max_fd)
138 {
139 max_fd = SocketDescriptor[i];
140 }
141 }
142 return max_fd;
143}
144
145
146
147
148/*
149Connect2Server connects NumberOfSockets TCP Sockets
150defined by SocketDescriptor
151to host defined by ServerIPaddress
152starting at Port StartPort, by adding 1 for each Socket
153
154return value is NumberOfSockets if successful
155it is zero if no Server was found and negative
156when connecting didn't work.
157The negative magnitude indicates which connection didn't work
158*/
159
160int Connect2Server( int *SocketDescriptor,
161 unsigned int NumberOfSockets,
162 unsigned int StartPort ,
163 char *ServerIPaddress ,
164 int verbose){
165
166 struct sockaddr_in SocketAddress[NumberOfSockets];
167 struct in_addr Serveripv4addr;
168
169 // Convert IP-Address to binary
170 if (inet_pton (AF_INET, ServerIPaddress, &Serveripv4addr) <= 0)
171 {
172 fprintf (stderr, "Error: network address not valid\n");
173 return 0;
174 }
175
176 if (verbose > 0) fprintf (stdout, "Trying to connect to %s...\n", ServerIPaddress);
177
178 for (unsigned int i = 0; i < NumberOfSockets; i++)
179 {
180 SocketAddress[i].sin_family = PF_INET;
181 SocketAddress[i].sin_port = htons ((unsigned short) StartPort + i);
182 SocketAddress[i].sin_addr = Serveripv4addr;
183
184 if (connect (SocketDescriptor[i], (struct sockaddr *) &SocketAddress[i], sizeof (SocketAddress[i])) == -1)
185 {
186 fprintf (stderr, "Error: Could not connect to server %s (port %d)\n", ServerIPaddress, StartPort + i);
187 return -i;
188 }
189 else if (verbose>0) {
190 printf ("Connected to %s:%d\n", ServerIPaddress, StartPort + i);
191 }
192 }
193
194 return NumberOfSockets;
195}
196
197/*
198CloseSockets closes NumberOfSockets TCP Sockets
199indicated by SocketDescriptor and frees the associated memory.
200*/
201int CloseSockets (int * SocketDescriptor ,
202 unsigned int NumberOfSockets)
203{
204 int close_return_val;
205 int return_val=0;
206
207 for (unsigned int i = 0; i < NumberOfSockets; i++)
208 {
209 if ( (close_return_val = close (SocketDescriptor[i])) != 0) {
210 fprintf (stderr, "Error: while trying to close SocketDescriptor[%d] = %d, close returned %d\n",
211 i ,
212 SocketDescriptor[i],
213 close_return_val );
214 return_val = close_return_val;
215 // no return close_return_val
216 // is performed here, because I want to try to close
217 // the other Ports before returning.
218 }
219 // ERRNO should better be checked and printed as well.
220 // TODO
221 }
222
223 return return_val;
224
225} // end of CloseSockets
226
Note: See TracBrowser for help on using the repository browser.