Develop and Download Open Source Software

Browse Subversion Repository

Contents of /connection/TcpipCtrl.cpp

Parent Directory Parent Directory | Revision Log Revision Log


Revision 279 - (show annotations) (download) (as text)
Wed Mar 12 05:28:19 2008 UTC (16 years, 1 month ago) by satofumi
File MIME type: text/x-c++src
File size: 5839 byte(s)
adjust tab index
1 /*!
2 \file
3 \brief TCP/IP Ú‘ą
4
5 \author Satofumi KAMIMURA
6
7 $Id$
8 */
9
10 #include "TcpipCtrl.h"
11 #include "SocketSet.h"
12 #include "RingBuffer.h"
13 #include "NetInit.h"
14 #include <string>
15
16 using namespace beego;
17
18
19 /*!
20 \brief TcpipCtrl ‚Ě“ŕ•”ƒNƒ‰ƒX
21 */
22 struct TcpipCtrl::pImpl : private NetInit {
23 std::string error_message;
24 TCPsocket socket;
25 SocketSet* socket_set;
26 SDLNet_SocketSet own_set;
27 RingBuffer<char> ring_buffer;
28 bool have_data;
29
30 pImpl(SocketSet* socketSet, TCPsocket tcp_socket)
31 : error_message("not connected."), socket(tcp_socket),
32 socket_set(socketSet), own_set(NULL), have_data(false) {
33 #if !HAVE_CONFIG_H || HAVE_LIBSDL_NET
34 if (socket_set == NULL) {
35 own_set = SDLNet_AllocSocketSet(1);
36 if (socket != NULL) {
37 addSocket(socket);
38 }
39 } else {
40 socket_set->add(socket);
41 }
42 #endif
43 }
44
45 ~pImpl(void) {
46 #if !HAVE_CONFIG_H || HAVE_LIBSDL_NET
47 disconnect();
48 if (own_set) {
49 SDLNet_FreeSocketSet(own_set);
50 }
51 #endif
52 }
53
54 void disconnect(void) {
55 #if !HAVE_CONFIG_H || HAVE_LIBSDL_NET
56 if (socket) {
57 if (socket_set) {
58 socket_set->del(socket);
59 } else {
60 SDLNet_TCP_DelSocket(own_set, socket);
61 }
62
63 //fprintf(stderr, " close %p.\n", socket);
64 SDLNet_TCP_Close(socket);
65 socket = NULL;
66 }
67 error_message = "disconnected.";
68 #endif
69 }
70
71 void addSocket(TCPsocket tcp_socket) {
72 #if !HAVE_CONFIG_H || HAVE_LIBSDL_NET
73 SDLNet_TCP_AddSocket(own_set, tcp_socket);
74 #endif
75 }
76
77 int update(int timeout, int size = 0) {
78 #if !HAVE_CONFIG_H || HAVE_LIBSDL_NET
79 enum { BufferSize = 1024 };
80 int require_size = (size > 0) ? size : BufferSize;
81 int filled = 0;
82 while (filled < require_size) {
83 if (socket_set == NULL) {
84 if (SDLNet_CheckSockets(own_set, (size == 0) ? 0 : timeout) <= 0) {
85 //if (SDLNet_CheckSockets(own_set, timeout) <= 0) {
86 break;
87 }
88 }
89 if (SDLNet_SocketReady(socket) <= 0) {
90 break;
91 }
92 char data[BufferSize];
93 int read_n = require_size - filled;
94 int n = SDLNet_TCP_Recv(socket, data,
95 (read_n > BufferSize) ? BufferSize : read_n);
96 if (n <= 0) {
97 disconnect();
98 return -1;
99 }
100 ring_buffer.put(data, n);
101 have_data = true;
102 filled += n;
103
104 if (socket_set != NULL) {
105 // SocketSet ‚đŽg‚Á‚˝ƒ`ƒFƒbƒN‚ĚŠÖŒW‚ŁA“ǂݍž‚Ý‚đs‚¤‚̂͂P‰ń‚Ě‚Ý
106 break;
107 }
108 }
109 return 0;
110 #else
111 return -1;
112 #endif
113 }
114 };
115
116
117 TcpipCtrl::TcpipCtrl(void) : pimpl(new pImpl(NULL, NULL)) {
118 }
119
120
121 TcpipCtrl::TcpipCtrl(SocketSet* socketSet, TCPsocket tcp_socket)
122 : pimpl(new pImpl(socketSet, tcp_socket)) {
123 }
124
125
126 TcpipCtrl::~TcpipCtrl(void) {
127 }
128
129
130 const char* TcpipCtrl::what(void) {
131 return pimpl->error_message.c_str();
132 }
133
134
135 bool TcpipCtrl::connect(const char* host, long port) {
136 #if !HAVE_CONFIG_H || HAVE_LIBSDL_NET
137 IPaddress ip;
138 int ret = SDLNet_ResolveHost(&ip, host, static_cast<short>(port));
139 if (ret < 0) {
140 // !!! ƒGƒ‰[o—Í
141 return false;
142 }
143
144 TCPsocket socket = SDLNet_TCP_Open(&ip);
145 if (socket == NULL) {
146 char strnum[13];
147 sprintf(strnum, "%ld", port);
148 pimpl->error_message =
149 std::string(SDLNet_GetError()) + " (" + host + ", " + strnum + ")";
150 return false;
151 }
152 //fprintf(stderr, " open %p\n", socket);
153 disconnect();
154 std::swap(socket, pimpl->socket);
155
156 // ƒ\ƒPƒbƒg‚đ“o˜^
157 if (pimpl->socket_set) {
158 pimpl->socket_set->add(pimpl->socket);
159 } else {
160 pimpl->addSocket(pimpl->socket);
161 }
162 pimpl->error_message = "connected.";
163 return true;
164 #else
165 return false;
166 #endif
167 }
168
169
170 void TcpipCtrl::disconnect(void) {
171 pimpl->disconnect();
172 }
173
174
175 /*!
176 \todo ŽóM‚đƒ`ƒFƒbƒN‚ľ‚ĐؒfŒŸo‚Ě•K—v‚Ş‚ ‚邊‚đŒŸ“˘‚ˇ‚éBŽŔ‘•Ď‚݁H
177 */
178 bool TcpipCtrl::isConnected(void) {
179 #if !HAVE_CONFIG_H || HAVE_LIBSDL_NET
180 return (pimpl->socket == NULL) ? false : true;
181 #else
182 return false;
183 #endif
184 }
185
186
187 bool TcpipCtrl::changeBaudrate(long baudrate) {
188 // ŽŔ‘•‚ľ‚Č‚˘
189 return true;
190 }
191
192
193 int TcpipCtrl::send(const char* data, int size) {
194 #if !HAVE_CONFIG_H || HAVE_LIBSDL_NET
195 if (! isConnected()) {
196 return -1;
197 }
198 return SDLNet_TCP_Send(pimpl->socket, const_cast<char*>(data), size);
199 #else
200 return -1;
201 #endif
202 }
203
204
205 int TcpipCtrl::recv(char* data, int size, int timeout) {
206 #if !HAVE_CONFIG_H || HAVE_LIBSDL_NET
207 if (((isConnected() == false) || (size <= 0))
208 && (pimpl->have_data == false)) {
209 return 0;
210 }
211 // ŽóMƒf[ƒ^‚̍XV
212 if ((pimpl->update(timeout) < 0) && (pimpl->have_data == false)) {
213 // Ř’f‚đŒŸo
214 return -1;
215 }
216
217 // —v‹•Ş‚ž‚ŻŽóMƒf[ƒ^‚Ş‚ ‚ę‚΁A•Ô‚ˇ
218 int filled = pimpl->ring_buffer.size();
219 if (filled >= size) {
220 pimpl->ring_buffer.get(data, size);
221 pimpl->have_data = ! pimpl->ring_buffer.empty();
222 return size;
223 }
224
225 // ŽóM‚Ĺ‚Ť‚˝ƒf[ƒ^‚đ•Ô‚ˇ
226 int left = size - filled;
227 if ((pimpl->own_set != NULL) && (pimpl->update(timeout, left) < 0)
228 && (pimpl->have_data == false)) {
229 // Ř’f‚đŒŸo
230 return -1;
231 }
232
233 // size() ‚đŒÄ‚Ô‚Ć update(0) ‚ތĂ΂ę‚é‚˝‚ß
234 filled = pimpl->ring_buffer.size();
235 pimpl->ring_buffer.get(data, filled);
236 pimpl->have_data = ! pimpl->ring_buffer.empty();
237
238 return filled;
239 #else
240 return -1;
241 #endif
242 }
243
244
245 int TcpipCtrl::size(int timeout) {
246 if ((pimpl->update(timeout) < 0) && (pimpl->have_data == false)) {
247 return -1;
248 }
249 return pimpl->ring_buffer.size();
250 }
251
252
253 void TcpipCtrl::clear(void) {
254 pimpl->ring_buffer.clear();
255 }
256
257
258 TCPsocket TcpipCtrl::getNetSocket(void) {
259 return pimpl->socket;
260 }
261
262
263 void TcpipCtrl::skip(int total_timeout) {
264 clear();
265
266 char buffer[BUFSIZ];
267 int total = 0;
268 int n;
269
270 enum { EachTimeout = 10 };
271 do {
272 n = recv(buffer, BUFSIZ, EachTimeout);
273 total += EachTimeout;
274 } while ((n > 0) && ((total_timeout > 0) && (total < total_timeout)));
275 }
276
277
278 void TcpipCtrl::flush(void) {
279 // !!!
280 }

Back to OSDN">Back to OSDN
ViewVC Help
Powered by ViewVC 1.1.26