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

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

Ajout classes de transfert DMA vers Ethernet et lecture ethernet, Reza 29/04/2010

File size: 5.8 KB
RevLine 
[3542]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>
[3639]15#include <stdlib.h>
16#include <string.h>
[3542]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.
[3757]25 The Close() method should be called explicitly.
[3542]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{
[3757]43 Set(a);
44}
45
46
47/* --Methode-- */
48Socket::~Socket()
49{
50 // Close();
51}
52
53/* --Methode-- */
54void Socket::Set(Socket const & a)
55{
[3542]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// extern int errno;
100
101/* --Methode-- */
102int Socket::Close()
103{
104 if (skt<0) return 0;
105 int rc=-1;
106 rc = shutdown(skt, SHUT_RDWR);
107 if(rc < 0)
108 cout << "Socket::Close() Erreur: Pb shutdown() ErrNo="
109 << errno << endl;
110
111 rc = close(skt);
112 if(rc < 0)
113 cout << "Socket::Close() Erreur: Pb close() ErrNo="
114 << errno << endl;
115 skt = -1;
116 return(0);
117}
118
119
120/*!
121 \class SOPHYA::ServerSocket
122 \ingroup SysTools
123 \brief Socket wrapper class for the server side
124*/
125
126/* --Methode-- */
127ServerSocket::ServerSocket(int port, int nconmax)
128 : Socket()
129{
130 int s,rc;
131 s = socket(AF_INET, SOCK_STREAM, 0);
132 if (s < 0) {
133 cout << "ServerSocket() Pb socket() ErrNo=" << errno << endl;
134 throw SocketException("ServerSocket() Pb socket()");
135 }
136 skt = s;
137 if (nconmax <= 1) nconmax = 1;
138 NConMax = nconmax;
139 nclitot = 0;
140
141 portid = port;
142 ipskt.sin_family = AF_INET;
143 ipskt.sin_port = htons(port);
144 ipskt.sin_addr.s_addr = INADDR_ANY;
145 /* Je fais un cast explicit de sockaddr_in * (Internet) en sockaddr * */
146 rc = bind(skt, (struct sockaddr *)(&ipskt), sizeof(ipskt));
147 if (rc < 0) {
148 Close();
149 cout << "ServerSocket() Pb bind() ErrNo=" << errno << endl;
150 throw SocketException("ServerSocket() Pb bind()");
151 }
152}
153
154/* --Methode-- */
155Socket ServerSocket::WaitClientConnection()
156{
157 int rc,s,len;
158 struct sockaddr_in cli;
159
160 rc = listen(skt, NConMax);
161 if (rc < 0) {
162 cout << "ServerSocket::WaitClientConnection() Pb listen() ErrNo="
163 << errno << endl;
164 throw SocketException("ServerSocket::WaitClientConnection() Pb listen()");
165 }
166
167 /* Je fais un cast explicit de sockaddr_in * (Internet) en sockaddr * */
168 socklen_t sl = sizeof(cli);
169 s = accept(skt, (struct sockaddr *)(&cli), &sl);
170 if(s < 0) {
171 cout << "ServerSocket::WaitClientConnection() Pb accpet() ErrNo="
172 << errno << endl;
173 throw SocketException("ServerSocket::WaitClientConnection() Pb accept()");
174 }
175 nclitot++;
176
177 return Socket(s);
178}
179
180
181/*!
182 \class SOPHYA::ClientSocket
183 \ingroup SysTools
184 \brief Socket wrapper class for the client side
185*/
186
187/* --Methode-- */
188ClientSocket::ClientSocket(string const& srvname, int port)
189 : Socket()
190{
191 InitConnection(srvname.c_str(), port);
192}
193
194/* --Methode-- */
195ClientSocket::ClientSocket(const char* srvname, int port)
196 : Socket()
197{
198 InitConnection(srvname, port);
199}
200
201/* --Methode-- */
[3757]202ClientSocket::ClientSocket(ClientSocket const& a)
203 : Socket(a)
204{
205 portid=a.portid;
206 ipskt=a.ipskt;
207}
208
209
210/* --Methode-- */
211void ClientSocket::SetC(ClientSocket const& a)
212{
213 Set(a);
214 portid=a.portid;
215 ipskt=a.ipskt;
216 return;
217}
218
219
220/* --Methode-- */
[3542]221void ClientSocket::InitConnection(const char* name, int port)
222{
223 struct hostent *server;
224 int s,rc;
225#if defined(Linux) || defined(linux)
226 typedef unsigned long in_addr_t;
227#endif
228 in_addr_t inad;
229
230 server = NULL;
231 /* Try to find out if this is a known machine name */
232 server = gethostbyname(name);
233 if(!server) {
234 /* Try it as an internet address a.b.c.d */
235 /* inad = inet_addr(name);
236 if(inad == INADDR_NONE) {
237 cout << "ClientSocket() Host identification failed inet_addr("
238 << name << ")" << endl;
239 throw SocketException("ClientSocket() Host identification failed ");
240 }
241 */
242 server = gethostbyaddr(name, strlen(name), AF_INET);
243 }
244 if(!server) {
245 cout << "ClientSocket() Host identification failed (2) for"
246 << name << endl;
247 throw SocketException("ClientSocket() Host identification failed (2)");
248 }
249
250 ipskt.sin_family = AF_INET;
251 ipskt.sin_port = htons(port);
252 memcpy(&(ipskt.sin_addr), server->h_addr, server->h_length);
253 s = socket(AF_INET, SOCK_STREAM, 0);
254 if (s < 0) {
255 cout << "ClientSocket() Erreur: Pb socket() ErrNo=" << errno << endl;
256 throw SocketException("ClientSocket() Erreur: Pb socket()");
257 }
258
259
260 skt = s;
261 portid = port;
262/* Je fais un cast explicit de sockaddr_in * (Internet) en sockaddr * */
263 rc = connect(skt, (struct sockaddr *)(&ipskt), sizeof(struct sockaddr_in));
264 if (rc < 0) {
265 cout << "ClientSocket() Erreur: Pb connect() ErrNo=" << errno << endl;
266 Close();
267 throw SocketException("ClientSocket() Erreur: Pb connect()");
268 }
269}
Note: See TracBrowser for help on using the repository browser.