source: BAORadio/libindi/v1/drivers/telescope/Socket.cpp@ 689

Last change on this file since 689 was 493, checked in by frichard, 15 years ago

Le programme gère mieux les connexion/déconnexion des microcontrôleurs.

File size: 4.6 KB
Line 
1// Implementation of the Socket class.
2
3
4#include "Socket.h"
5#include "string.h"
6#include <string.h>
7#include <errno.h>
8#include <fcntl.h>
9#include <iostream>
10#include <netinet/tcp.h>
11
12
13
14Socket::Socket() :
15 m_sock ( -1 )
16{
17
18 memset ( &m_addr,
19 0,
20 sizeof ( m_addr ) );
21}
22
23Socket::~Socket()
24{
25 if ( is_valid() )
26 ::close ( m_sock );
27}
28
29bool Socket::create()
30{
31 m_sock = socket ( AF_INET,
32 SOCK_STREAM,
33 0); //IPPROTO_TCP
34
35 if ( ! is_valid() )
36 return false;
37
38
39 int on = 1;
40
41 if ( setsockopt ( m_sock, SOL_SOCKET, SO_REUSEADDR, ( const char* ) &on, sizeof ( on ) ) == -1 ) return false;
42
43 // Réduire les délais lors des transmissions TCP/IP
44 // Voir article à l'adresse
45 // http://www.redhat.com/docs/en-US/Red_Hat_Enterprise_MRG/1.0/html/Realtime_Tuning_Guide/sect-Realtime_Tuning_Guide-Application_Tuning_and_Deployment-TCP_NODELAY_and_Small_Buffer_Writes.html
46
47 if ( setsockopt(m_sock, SOL_TCP, TCP_NODELAY, (const char*) &on, sizeof(on)) < 0 ) return false;
48
49 return true;
50}
51
52
53
54bool Socket::bind ( const int port )
55{
56 if ( ! is_valid() ) return false;
57
58 m_addr.sin_family = AF_INET;
59 m_addr.sin_addr.s_addr = INADDR_ANY;
60 m_addr.sin_port = htons ( port );
61
62 int bind_return = ::bind ( m_sock,
63 ( struct sockaddr * ) &m_addr,
64 sizeof ( m_addr ) );
65
66
67 if ( bind_return == -1 ) return false;
68
69 return true;
70}
71
72
73bool Socket::listen() const
74{
75 if ( ! is_valid() ) return false;
76
77 int listen_return = ::listen ( m_sock, MAXCONNECTIONS );
78
79 if ( listen_return == -1 ) return false;
80
81 return true;
82}
83
84
85bool Socket::accept ( Socket& new_socket ) const
86{
87 int addr_length = sizeof ( m_addr );
88
89 new_socket.m_sock = ::accept ( m_sock, ( sockaddr * ) &m_addr, ( socklen_t * ) &addr_length );
90
91 if ( new_socket.m_sock <= 0 ) return false;
92
93 return true;
94}
95
96
97bool Socket::shutdown()
98{
99 int ret = 0;
100
101 if ( is_valid() )
102 ret = ::shutdown ( m_sock, 2 );
103
104 m_sock=-1;
105
106 if ( ret == 0 ) return true;
107
108 return false;
109}
110
111
112bool Socket::send ( const std::string s ) const
113{
114 if ( ! is_valid() ) return false;
115
116 int status = ::send ( m_sock, s.c_str(), s.size(), MSG_NOSIGNAL);
117
118 if ( status == -1 ) return false;
119
120 return true;
121}
122
123
124int Socket::recv ( std::string& s ) const
125{
126 int sel;
127 fd_set r;
128 struct timeval timeout;
129
130 if ( ! is_valid() ) return false;
131
132 s="";
133
134 timeout.tv_sec = 0; // initialise le timeout, ici les secondes
135 timeout.tv_usec = 1; // les microsecondes
136
137 FD_ZERO(&r); // initialise la liste de fd
138 FD_SET(m_sock, &r); // ajoute la socket dans la liste des fd
139 sel = select(m_sock + 1, &r, NULL, NULL, &timeout);
140 if (sel < 0) // select a rencontré un problÚme
141 {
142 return -1;
143 }
144 else if (sel == 0) // timeout
145 {
146 return 1;
147 }
148 else // quelque chose est à lire sur un file descriptor
149 {
150 if (FD_ISSET(m_sock, &r)) // si la socket est prête à être lue
151 {
152 char buf [ MAXRECV + 1 ];
153
154 s = "";
155
156 memset ( buf, 0, MAXRECV + 1 );
157
158 int status = ::recv ( m_sock, buf, MAXRECV, 0 );
159
160 if ( status == -1 )
161 {
162 // là, nous ne sommes pas en présence d'une vraie erreur
163 // car le mode non-bloquant est activé ici
164 // (consulter la doc de la fct recv...)
165 if (errno == EAGAIN )
166 {
167 return 0;
168 }
169
170 return -1;
171 }
172 else if ( status == 0 )
173 {
174 return 0;
175 }
176 else
177 {
178 s = buf;
179 return status;
180 }
181 }
182 }
183}
184
185
186
187bool Socket::connect ( const std::string host, const int port )
188{
189 if ( ! is_valid() ) return false;
190
191 memset ( &m_addr,
192 0,
193 sizeof ( m_addr ) );
194
195
196 m_addr.sin_family = AF_INET;
197 m_addr.sin_port = htons ( port );
198
199 int status = inet_pton ( AF_INET, host.c_str(), &m_addr.sin_addr );
200
201 if ( errno == EAFNOSUPPORT ) return false;
202
203 status = ::connect ( m_sock, ( sockaddr * ) &m_addr, sizeof ( m_addr ) );
204
205 if ( status == 0 ) return true;
206
207 return false;
208}
209
210void Socket::set_non_blocking ( const bool b )
211{
212 int opts;
213
214 opts = fcntl ( m_sock,F_GETFL );
215
216 if ( opts < 0 )
217 {
218 return;
219 }
220
221 if ( b )
222 opts = ( opts | O_NONBLOCK );
223 else
224 opts = ( opts & ~O_NONBLOCK );
225
226 fcntl ( m_sock,
227 F_SETFL,opts );
228
229}
230
231
232std::string Socket::recupip() const
233{
234 return inet_ntoa(m_addr.sin_addr);
235}
Note: See TracBrowser for help on using the repository browser.