source: Sophya/trunk/AddOn/TAcq/swrapsock.cc@ 3902

Last change on this file since 3902 was 3897, checked in by ansari, 15 years ago

Amelioration des classes PCIEToEthernet et EthernetReader pour eviter des situations de blocage lorsque lecture avec ForceSameFrameCounter, Reza 04/10/2010

File size: 7.2 KB
Line 
1#ifdef OSF1
2#define _XOPEN_SOURCE 500
3#endif
4#include "swrapsock.h"
5#include "sopnamsp.h"
6
7#include <time.h>
8
9#include <arpa/inet.h>
10#include <netdb.h>
11#include <sys/errno.h>
12#include <unistd.h>
13
14#include <iostream>
15#include <stdlib.h>
16#include <string.h>
17
18/*!
19 \class SOPHYA::Socket
20 \ingroup SysTools
21 \brief Base class for server and client sockets.
22
23 The class Socket is not intended for direct use. Only the derived classes
24 ServerSocket and ClientSocket should be used.
25 The Close() method should be called explicitly.
26*/
27
28/* --Methode-- */
29Socket::Socket(int s)
30{
31 skt = s;
32 tstart = tlast = (long)time(NULL);
33 totsnd = totrcv = 0;
34 dts = dtr = 0;
35 nbbs = nbbr = 0;
36 lstnbb = 0; lstdt = 0;
37 errcnt = 0;
38}
39
40/* --Methode-- */
41Socket::Socket(Socket const & a)
42{
43 Set(a);
44}
45
46
47/* --Methode-- */
48Socket::~Socket()
49{
50 // Close();
51}
52
53/* --Methode-- */
54void Socket::Set(Socket const & a)
55{
56 skt = a.skt;
57 tstart = a.tstart; tlast = a.tlast;
58 totsnd = a.totsnd; totrcv = a.totrcv;
59 dts = a.dts; dtr = a.dtr;
60 nbbs = a.nbbs; nbbr = a.nbbr;
61 lstnbb = a.lstnbb; lstdt = a.lstdt;
62 errcnt = a.errcnt;
63}
64
65
66/* --Methode-- */
67size_t Socket::Send(const char * buff, size_t len, int flag)
68{
69 ssize_t rc;
70 rc = send(skt, buff, len, flag);
71 if (rc > 0) {
72 // tlast = (long)time(NULL);
73 totsnd += rc;
74 return(rc);
75 }
76 else return 0;
77}
78
79/* --Methode-- */
80size_t Socket::Receive(char * buff, size_t len, int flag)
81{
82 ssize_t rc;
83 // int fromlen = 0;
84 bool encore = true;
85 while (encore) {
86 rc = recv(skt, buff, len, flag);
87 // rc = recvfrom(skt, buff, len, flag, NULL, &fromlen);
88 if ((rc < 1) && (errno == EAGAIN)) usleep(20000);
89 else encore = false;
90 }
91 if (rc > 0) {
92 // tlast = (long)time(NULL);
93 totrcv += rc;
94 return(rc);
95 }
96 else return 0;
97}
98
99/* --Methode-- */
100size_t Socket::SendAll(const char * buff, size_t len)
101{
102 size_t nst = 0;
103 int ntry = 0;
104 while (nst < len) {
105 size_t ns = Send(buff+nst, len-nst);
106 ntry++;
107 if (ns < 1) break;
108 nst += ns;
109 }
110 if (nst < len) {
111 cout << " Socket::SendAll() / ERROR ! ntry=" << ntry
112 << " nst=" << nst << " len=" << len << endl;
113 throw SocketException("Socket::SendAll() Error NBytesSent < len ");
114 }
115 return nst;
116}
117
118/* --Methode-- */
119size_t Socket::ReceiveAll(char * buff, size_t len)
120{
121 size_t nrt = 0;
122 int ntry = 0;
123 while (nrt < len) {
124 size_t nr = Receive(buff+nrt, len-nrt);
125 ntry++;
126 if (nr < 1) break;
127 nrt += nr;
128 }
129 if (nrt < len) {
130 cout << " Socket::ReceiveAll / ERROR ! ntry=" << ntry
131 << " nrt=" << nrt << " len=" << len << endl;
132 throw SocketException("Socket::ReceiveAll() Error NBytesRecv < len ");
133 }
134 return nrt;
135}
136
137// extern int errno;
138
139/* --Methode-- */
140int Socket::Close()
141{
142 if (skt<0) return 0;
143 int rc=-1;
144 rc = shutdown(skt, SHUT_RDWR);
145 if(rc < 0)
146 cout << "Socket::Close() Erreur: Pb shutdown() ErrNo="
147 << errno << endl;
148
149 rc = close(skt);
150 if(rc < 0)
151 cout << "Socket::Close() Erreur: Pb close() ErrNo="
152 << errno << endl;
153 skt = -1;
154 return(0);
155}
156
157
158/*!
159 \class SOPHYA::ServerSocket
160 \ingroup SysTools
161 \brief Socket wrapper class for the server side
162*/
163
164/* --Methode-- */
165ServerSocket::ServerSocket(int port, int nconmax)
166 : Socket()
167{
168 int s,rc;
169 s = socket(AF_INET, SOCK_STREAM, 0);
170 if (s < 0) {
171 cout << "ServerSocket() Pb socket() ErrNo=" << errno << endl;
172 throw SocketException("ServerSocket() Pb socket()");
173 }
174 skt = s;
175 if (nconmax <= 1) nconmax = 1;
176 NConMax = nconmax;
177 nclitot = 0;
178
179 portid = port;
180 ipskt.sin_family = AF_INET;
181 ipskt.sin_port = htons(port);
182 ipskt.sin_addr.s_addr = INADDR_ANY;
183 /* Je fais un cast explicit de sockaddr_in * (Internet) en sockaddr * */
184 rc = bind(skt, (struct sockaddr *)(&ipskt), sizeof(ipskt));
185 if (rc < 0) {
186 Close();
187 cout << "ServerSocket() Pb bind() ErrNo=" << errno << endl;
188 throw SocketException("ServerSocket() Pb bind()");
189 }
190}
191
192/* --Methode-- */
193Socket ServerSocket::WaitClientConnection()
194{
195 int rc,s,len;
196 struct sockaddr_in cli;
197
198 rc = listen(skt, NConMax);
199 if (rc < 0) {
200 cout << "ServerSocket::WaitClientConnection() Pb listen() ErrNo="
201 << errno << endl;
202 throw SocketException("ServerSocket::WaitClientConnection() Pb listen()");
203 }
204
205 /* Je fais un cast explicit de sockaddr_in * (Internet) en sockaddr * */
206 socklen_t sl = sizeof(cli);
207 s = accept(skt, (struct sockaddr *)(&cli), &sl);
208 if(s < 0) {
209 cout << "ServerSocket::WaitClientConnection() Pb accpet() ErrNo="
210 << errno << endl;
211 throw SocketException("ServerSocket::WaitClientConnection() Pb accept()");
212 }
213 nclitot++;
214
215 return Socket(s);
216}
217
218
219/* --Methode-- */
220int ServerSocket::Close()
221{
222 if (skt<0) return 0;
223 int rc=-1;
224 /* il ne faut apparemment pas faire shutdown sur un socket serveur (non connected - ENOTCONN )
225 rc = shutdown(skt, SHUT_RDWR);
226 if(rc < 0)
227 cout << "Socket::Close() Erreur: Pb shutdown() ErrNo="
228 << errno << endl;
229 */
230 rc = close(skt);
231 if(rc < 0)
232 cout << "ServerSocket::Close() Erreur: Pb close() ErrNo="
233 << errno << endl;
234 skt = -1;
235 return(0);
236}
237
238
239/*!
240 \class SOPHYA::ClientSocket
241 \ingroup SysTools
242 \brief Socket wrapper class for the client side
243*/
244
245/* --Methode-- */
246ClientSocket::ClientSocket(string const& srvname, int port)
247 : Socket()
248{
249 InitConnection(srvname.c_str(), port);
250}
251
252/* --Methode-- */
253ClientSocket::ClientSocket(const char* srvname, int port)
254 : Socket()
255{
256 InitConnection(srvname, port);
257}
258
259/* --Methode-- */
260ClientSocket::ClientSocket(ClientSocket const& a)
261 : Socket(a)
262{
263 portid=a.portid;
264 ipskt=a.ipskt;
265}
266
267
268/* --Methode-- */
269void ClientSocket::SetC(ClientSocket const& a)
270{
271 Set(a);
272 portid=a.portid;
273 ipskt=a.ipskt;
274 return;
275}
276
277
278/* --Methode-- */
279void ClientSocket::InitConnection(const char* name, int port)
280{
281 struct hostent *server;
282 int s,rc;
283#if defined(Linux) || defined(linux)
284 typedef unsigned long in_addr_t;
285#endif
286 in_addr_t inad;
287
288 server = NULL;
289 /* Try to find out if this is a known machine name */
290 server = gethostbyname(name);
291 if(!server) {
292 /* Try it as an internet address a.b.c.d */
293 /* inad = inet_addr(name);
294 if(inad == INADDR_NONE) {
295 cout << "ClientSocket() Host identification failed inet_addr("
296 << name << ")" << endl;
297 throw SocketException("ClientSocket() Host identification failed ");
298 }
299 */
300 server = gethostbyaddr(name, strlen(name), AF_INET);
301 }
302 if(!server) {
303 cout << "ClientSocket() Host identification failed (2) for"
304 << name << endl;
305 throw SocketException("ClientSocket() Host identification failed (2)");
306 }
307
308 ipskt.sin_family = AF_INET;
309 ipskt.sin_port = htons(port);
310 memcpy(&(ipskt.sin_addr), server->h_addr, server->h_length);
311 s = socket(AF_INET, SOCK_STREAM, 0);
312 if (s < 0) {
313 cout << "ClientSocket() Erreur: Pb socket() ErrNo=" << errno << endl;
314 throw SocketException("ClientSocket() Erreur: Pb socket()");
315 }
316
317
318 skt = s;
319 portid = port;
320/* Je fais un cast explicit de sockaddr_in * (Internet) en sockaddr * */
321 rc = connect(skt, (struct sockaddr *)(&ipskt), sizeof(struct sockaddr_in));
322 if (rc < 0) {
323 cout << "ClientSocket() Erreur: Pb connect() ErrNo=" << errno << endl;
324 Close();
325 throw SocketException("ClientSocket() Erreur: Pb connect()");
326 }
327}
Note: See TracBrowser for help on using the repository browser.