|
1 /* |
|
2 * Copyright (c) 1997-2009 Nokia Corporation and/or its subsidiary(-ies). |
|
3 * All rights reserved. |
|
4 * This component and the accompanying materials are made available |
|
5 * under the terms of "Eclipse Public License v1.0" |
|
6 * which accompanies this distribution, and is available |
|
7 * at the URL "http://www.eclipse.org/legal/epl-v10.html". |
|
8 * |
|
9 * Initial Contributors: |
|
10 * Nokia Corporation - initial contribution. |
|
11 * |
|
12 * Contributors: |
|
13 * |
|
14 * Description: |
|
15 * Test of AF_INET stream sockets |
|
16 * |
|
17 * |
|
18 */ |
|
19 |
|
20 |
|
21 |
|
22 #include <stdio.h> |
|
23 #include <errno.h> |
|
24 #include <stdlib.h> |
|
25 #include <string.h> |
|
26 #include <unistd.h> |
|
27 #include <sys/types.h> |
|
28 #include <sys/socket.h> |
|
29 #include <sys/ioctl.h> |
|
30 #include <libc/netinet/in.h> |
|
31 #include <libc/arpa/inet.h> |
|
32 #include <netdb.h> |
|
33 |
|
34 #include "CTEST.H" /* includes C interface to EPOC32 threads, and SpawnPosixServer */ |
|
35 |
|
36 test_Data; |
|
37 |
|
38 struct sockaddr_in testaddr; |
|
39 |
|
40 unsigned short int port = 2001; |
|
41 |
|
42 /** |
|
43 @SYMTestCaseID SYSLIB-STDLIB-CT-1059 |
|
44 @SYMTestCaseDesc Tests for AF_INET stream sockets |
|
45 @SYMTestPriority High |
|
46 @SYMTestActions Tests for simple operations on stream sockets,open,bind,get socket name,listen operations and test for error code |
|
47 @SYMTestExpectedResults Test must not fail |
|
48 @SYMREQ REQ0000 |
|
49 */ |
|
50 void testSimple() |
|
51 { |
|
52 int fd1, fd2; |
|
53 |
|
54 size_t addrsize; |
|
55 int err; |
|
56 struct sockaddr_in addr1, addr2; |
|
57 int optionbuf[20]; |
|
58 size_t optionsize; |
|
59 |
|
60 test_Next("Create stream sockets"); |
|
61 fd1=socket(AF_INET, SOCK_STREAM, 0); |
|
62 test_ok(fd1>=0); |
|
63 |
|
64 fd2=socket(AF_INET, SOCK_STREAM, 0); |
|
65 test_ok(fd2>=0); |
|
66 |
|
67 test_Next("Some binding tests"); |
|
68 |
|
69 addr1.sin_family=2061; |
|
70 addr1.sin_port=htons(65530); |
|
71 addr1.sin_addr.s_addr=htonl(0x11223344); |
|
72 err=bind(fd1, (struct sockaddr*)&addr1, sizeof(addr1)); /* wrong family, port out of range */ |
|
73 test_errno(err<0,ENOENT); |
|
74 |
|
75 addr1=testaddr; |
|
76 addr1.sin_port=htons(port); |
|
77 err=bind(fd1, (struct sockaddr*)&addr1, sizeof(addr1)); |
|
78 test_ok(err==0); |
|
79 |
|
80 addr1=testaddr; |
|
81 addr1.sin_port=htons((unsigned short int)(port+1)); |
|
82 err=bind(fd1, (struct sockaddr*)&addr1, sizeof(addr1)); /* already bound */ |
|
83 test_errno(err!=0, EEXIST); |
|
84 |
|
85 test_Next("Get associated addresses"); |
|
86 |
|
87 addrsize=sizeof(addr2); |
|
88 err=getsockname(fd1,(struct sockaddr*)&addr2,&addrsize); |
|
89 test_ok(err==0); |
|
90 test(addr2.sin_family==AF_INET); |
|
91 test(addr2.sin_port==htons(port)); |
|
92 test(addrsize<=sizeof(addr2)); |
|
93 |
|
94 addrsize=sizeof(addr2); |
|
95 err=getpeername(fd1,(struct sockaddr*)&addr2,&addrsize); /* not connected */ |
|
96 test_errno(err!=0,-2); /* OMISSION - can't report proper reason for failure */ |
|
97 |
|
98 addrsize=sizeof(addr2); |
|
99 err=getsockname(fd2,(struct sockaddr*)&addr2,&addrsize); /* not bound */ |
|
100 test_errno(err!=0,-2); /* OMISSION - can't report proper reason for failure */ |
|
101 |
|
102 test_Next("More binding"); |
|
103 |
|
104 addr1=testaddr; |
|
105 addr1.sin_port=htons(port); |
|
106 err=bind(fd2, (struct sockaddr*)&addr1, sizeof(addr1)); /* address in use */ |
|
107 test_errno(err!=0, EACCES); |
|
108 |
|
109 addr1=testaddr; |
|
110 addr1.sin_port=0; |
|
111 err=bind(fd2, (struct sockaddr*)&addr1, sizeof(addr1)); /* unspecified port number */ |
|
112 test_ok(err==0); |
|
113 |
|
114 addrsize=sizeof(addr2); |
|
115 err=getsockname(fd2,(struct sockaddr*)&addr2,&addrsize); |
|
116 test_ok(err==0); |
|
117 test(addr2.sin_family==AF_INET); |
|
118 test(addrsize<=sizeof(addr2)); |
|
119 test(addr2.sin_port!=htons(port)); |
|
120 test(addr2.sin_port!=0); |
|
121 { |
|
122 unsigned short port=ntohs(addr2.sin_port); |
|
123 test(port>=IPPORT_RESERVED); |
|
124 /* NB. TCPIP 030 has 9999 for IPPORT_USERRESERVED, but TCPIP 031 dropped it to 5000 */ |
|
125 test(port<=IPPORT_USERRESERVED); |
|
126 printf(" allocated port %d\n",port); |
|
127 } |
|
128 |
|
129 err=listen(fd1,1); |
|
130 test_ok(err==0); |
|
131 |
|
132 test_Next("Socket options"); |
|
133 |
|
134 optionbuf[0]=3500000; /* implausible size */ |
|
135 optionsize=sizeof(optionbuf[0]); |
|
136 err=getsockopt(fd1,SOL_SOCKET,SO_SNDBUF,optionbuf,&optionsize); |
|
137 test_ok(err==0); |
|
138 test(optionbuf[0]!=3500000); |
|
139 |
|
140 optionbuf[0]=7*1024; |
|
141 optionsize=sizeof(optionbuf[0]); |
|
142 err=setsockopt(fd1,SOL_SOCKET,SO_SNDBUF,optionbuf,optionsize); |
|
143 test_ok(err==0); |
|
144 |
|
145 optionbuf[0]=3500000; /* implausible size */ |
|
146 optionsize=sizeof(optionbuf[0]); |
|
147 err=getsockopt(fd1,SOL_SOCKET,SO_SNDBUF,optionbuf,&optionsize); |
|
148 test_ok(err==0); |
|
149 test(optionbuf[0]==7*1024); |
|
150 |
|
151 optionbuf[0]=1; |
|
152 optionsize=sizeof(optionbuf[0]); |
|
153 err=getsockopt(fd1,SOL_SOCKET,1234,optionbuf,&optionsize); /* invalid option */ |
|
154 test_errno(err<0,ENOSYS); |
|
155 test(optionbuf[0]==1); |
|
156 |
|
157 optionbuf[0]=13; |
|
158 optionsize=sizeof(optionbuf[0]); |
|
159 err=setsockopt(fd1,SOL_SOCKET,1234,optionbuf,optionsize); /* invalid option */ |
|
160 test_errno(err<0,ENOSYS); |
|
161 test(optionbuf[0]==13); |
|
162 |
|
163 err=close(fd1); |
|
164 test_ok(err==0); |
|
165 |
|
166 err=close(fd2); |
|
167 test_ok(err==0); |
|
168 } |
|
169 |
|
170 /* Client and server take it in turns to send, starting with the client. |
|
171 * Each matches the message they receive with the string expected |
|
172 */ |
|
173 char *message_sequence[] = { |
|
174 "Hello from client", |
|
175 "Hello from server", |
|
176 "Test of send", |
|
177 "Test of recv", |
|
178 "Try sendto", |
|
179 "Try recvfrom", |
|
180 "Try sendto again", |
|
181 "Try recvfrom again", |
|
182 "Send to shutdown socket", |
|
183 "Send to closed socket", |
|
184 0 |
|
185 }; |
|
186 |
|
187 /** |
|
188 @SYMTestCaseID SYSLIB-STDLIB-CT-1060 |
|
189 @SYMTestCaseDesc Tests for server socket |
|
190 @SYMTestPriority High |
|
191 @SYMTestActions Create a steam socket,bind and test for a transmission process.Check for error codes |
|
192 @SYMTestExpectedResults Test must not fail |
|
193 @SYMREQ REQ0000 |
|
194 */ |
|
195 void testServer() |
|
196 { |
|
197 int fd1,fd2,nbytes,i; |
|
198 size_t addrsize; |
|
199 int err; |
|
200 struct sockaddr_in addr1, addr2; |
|
201 char buf[80]; |
|
202 char **mp = message_sequence; |
|
203 static int randbuf[10000]; |
|
204 |
|
205 fd1=fd2=nbytes=i=0; |
|
206 |
|
207 /* Fill the buffer with a predetermined random number sequence */ |
|
208 randbuf[0]=4441302; |
|
209 srand(randbuf[0]); |
|
210 for (i=1; i<10000; i++) |
|
211 randbuf[i]=rand(); |
|
212 |
|
213 |
|
214 test_Next("Create server socket"); |
|
215 fd1=socket(AF_INET, SOCK_STREAM, 0); |
|
216 test_ok(fd1>=0); |
|
217 |
|
218 #if 0 |
|
219 /* causes ESOCK to panic the client */ |
|
220 addrsize=sizeof(addr2); |
|
221 fd2=accept(fd1,&addr2,&addrsize); /* can't accept on an unbound socket */ |
|
222 test_ok(fd2<0); |
|
223 #endif |
|
224 |
|
225 IN_SET_LOOPBACK_ADDR(&addr1); |
|
226 addr1.sin_port=htons(port); |
|
227 err=bind(fd1, (struct sockaddr*)&addr1, sizeof(addr1)); |
|
228 test_ok(err==0); |
|
229 |
|
230 #if 0 |
|
231 /* causes ESOCK to panic the client */ |
|
232 addrsize=sizeof(addr2); |
|
233 fd2=accept(fd1,&addr2,&addrsize); /* can't accept before listening */ |
|
234 test_ok(fd2<0); |
|
235 #endif |
|
236 |
|
237 err=listen(fd1,1); |
|
238 test_ok(err==0); |
|
239 |
|
240 addrsize=sizeof(addr2); |
|
241 fd2=accept(fd1,(struct sockaddr*)&addr2,&addrsize); |
|
242 test_ok(fd2>=0); |
|
243 test(addr2.sin_family==AF_INET); |
|
244 test(addr2.sin_port!=htons(port)); |
|
245 test(addr2.sin_port!=0); |
|
246 test(addrsize<=sizeof(addr2)); |
|
247 |
|
248 test_Next("Server read/write"); |
|
249 |
|
250 /* read */ |
|
251 nbytes=strlen(*mp); |
|
252 err=read(fd2, buf, nbytes+1); |
|
253 test_ok(err==nbytes+1); |
|
254 test(strcmp(buf,*mp)==0); |
|
255 |
|
256 /* write */ |
|
257 mp++; |
|
258 nbytes=strlen(*mp); |
|
259 for (i=0; i<nbytes+1; i++) |
|
260 { |
|
261 err=write(fd2,(*mp)+i,1); |
|
262 test_ok(err==1); |
|
263 } |
|
264 |
|
265 test_Next("Server send/recv"); |
|
266 |
|
267 /* recv */ |
|
268 mp++; |
|
269 nbytes=strlen(*mp); |
|
270 err=recv(fd2, buf, sizeof(buf) ,0); |
|
271 test_ok(err==nbytes+1); |
|
272 test(strcmp(buf,*mp)==0); |
|
273 |
|
274 /* send */ |
|
275 mp++; |
|
276 nbytes=strlen(*mp); |
|
277 err=send(fd2, *mp, nbytes+1,0); |
|
278 test_ok(err==nbytes+1); |
|
279 |
|
280 /* recvfrom */ |
|
281 mp++; |
|
282 nbytes=strlen(*mp); |
|
283 addrsize=sizeof(addr2); |
|
284 addr2.sin_port=0; |
|
285 err=recvfrom(fd2, buf, nbytes+1,0,(struct sockaddr*)&addr2,&addrsize); |
|
286 /* |
|
287 memset(&buf[0],0, sizeof(buf)); |
|
288 err=recvfrom(fd2, buf, nbytes+1,0,0,0); |
|
289 */ |
|
290 test_ok(err==nbytes+1); |
|
291 test(strcmp(buf,*mp)==0); |
|
292 test(addr2.sin_family==AF_INET); |
|
293 test(addr2.sin_port!=htons(port)); |
|
294 test(addr2.sin_port!=0); |
|
295 test(addrsize<=sizeof(addr2)); |
|
296 |
|
297 /* sendto */ |
|
298 mp++; |
|
299 nbytes=strlen(*mp); |
|
300 addrsize=sizeof(addr1); |
|
301 err=sendto(fd2, *mp, nbytes+1,0,(struct sockaddr*)&addr1,addrsize); /* not allowed on streams */ |
|
302 test_errno(err<0,ENOSYS); |
|
303 err=send(fd2, *mp, nbytes+1,0); /* to keep synchronisation */ |
|
304 test_ok(err==nbytes+1); |
|
305 |
|
306 |
|
307 test_Next("Server revcfrom with null fromaddr"); |
|
308 /* recvfrom again*/ |
|
309 mp++; |
|
310 nbytes=strlen(*mp); |
|
311 memset(&buf[0],0xFF, sizeof(buf)); |
|
312 err=recvfrom(fd2, buf, nbytes+1,0,0,0); |
|
313 test_ok(err==nbytes+1); |
|
314 test(strcmp(buf,*mp)==0); |
|
315 |
|
316 /* sendto again*/ |
|
317 mp++; |
|
318 nbytes=strlen(*mp); |
|
319 addrsize=sizeof(addr1); |
|
320 err=send(fd2, *mp, nbytes+1,0); /* to keep synchronisation */ |
|
321 test_ok(err==nbytes+1); |
|
322 |
|
323 |
|
324 |
|
325 /* |
|
326 test_Next("Server shutdown transmission"); |
|
327 err=shutdown(fd2,1); |
|
328 test_ok(err==0); |
|
329 |
|
330 sleep(4); // so that the client's sleep(1) finishes before we awake |
|
331 |
|
332 mp++; |
|
333 nbytes=strlen(*mp); |
|
334 addrsize=sizeof(addr1); |
|
335 err=send(fd2, *mp, nbytes+1,0); |
|
336 test_errno(err<0,EPIPE); |
|
337 |
|
338 nbytes=strlen(*mp); |
|
339 err=recv(fd2, buf, nbytes+1,0); |
|
340 test_ok(err==nbytes+1); |
|
341 test(strcmp(buf,*mp)==0); |
|
342 |
|
343 err=close(fd2); |
|
344 test_ok(err==0); |
|
345 |
|
346 // Large transmission |
|
347 */ |
|
348 test_Next("Server large transfer"); |
|
349 |
|
350 addrsize=sizeof(addr2); |
|
351 fd2=accept(fd1,(struct sockaddr*)&addr2,&addrsize); |
|
352 test_ok(fd2>=0); |
|
353 test(addr2.sin_family==AF_INET); |
|
354 test(addr2.sin_port!=htons(port)); |
|
355 test(addr2.sin_port!=0); |
|
356 test(addrsize<=sizeof(addr2)); |
|
357 |
|
358 nbytes=sizeof(randbuf); |
|
359 err=write(fd2,(const char*)randbuf,nbytes); |
|
360 test_ok(err==nbytes); |
|
361 |
|
362 test_Next("Server close"); |
|
363 |
|
364 // err=shutdown(fd2,1); |
|
365 // test_ok(err==0); |
|
366 |
|
367 // sleep(4); |
|
368 |
|
369 err=close(fd2); |
|
370 test_ok(err==0); |
|
371 |
|
372 err=close(fd1); |
|
373 test_ok(err==0); |
|
374 } |
|
375 |
|
376 /** |
|
377 @SYMTestCaseID SYSLIB-STDLIB-CT-1061 |
|
378 @SYMTestCaseDesc Tests for client socket |
|
379 @SYMTestPriority High |
|
380 @SYMTestActions Create a steam socket,bind and test for a transmission process.Check for error codes |
|
381 @SYMTestExpectedResults Test must not fail |
|
382 @SYMREQ REQ0000 |
|
383 */ |
|
384 void testClient() |
|
385 { |
|
386 int fd1, nbytes, nbytes2, i, status; |
|
387 |
|
388 size_t addrsize; |
|
389 int err; |
|
390 struct sockaddr_in addr1, addr2; |
|
391 char buf[80]; |
|
392 char **mp = message_sequence; |
|
393 static int randbuf[10001]; |
|
394 |
|
395 test_Next("Create client socket"); |
|
396 fd1=socket(AF_INET, SOCK_STREAM, 0); |
|
397 test_ok(fd1>=0); |
|
398 |
|
399 sleep(5); /* give server a chance to run */ |
|
400 |
|
401 addr1=testaddr; |
|
402 addr1.sin_port=htons(port); |
|
403 addrsize=sizeof(addr1); |
|
404 err=connect(fd1,(struct sockaddr*)&addr1,addrsize); |
|
405 test_ok(err==0); |
|
406 |
|
407 addrsize=sizeof(addr2); |
|
408 err=getpeername(fd1,(struct sockaddr*)&addr2,&addrsize); |
|
409 test_ok(err==0); |
|
410 test(addr2.sin_family==AF_INET); |
|
411 test(addr2.sin_port==htons(port)); |
|
412 test(addrsize<=sizeof(addr2)); |
|
413 |
|
414 addrsize=sizeof(addr2); |
|
415 err=getsockname(fd1,(struct sockaddr*)&addr2,&addrsize); |
|
416 test_ok(err==0); |
|
417 test(addr2.sin_family==AF_INET); |
|
418 test(addr2.sin_port!=htons(port)); |
|
419 test(addr2.sin_port!=0); |
|
420 test(addrsize<=sizeof(addr2)); |
|
421 |
|
422 test_Next("Client read/write"); |
|
423 |
|
424 /* write */ |
|
425 nbytes=strlen(*mp); |
|
426 err=write(fd1, *mp, nbytes+1); |
|
427 test_ok(err==nbytes+1); |
|
428 |
|
429 /* read */ |
|
430 mp++; |
|
431 nbytes=strlen(*mp); |
|
432 err=read(fd1, buf, nbytes+1); |
|
433 test_ok(err==nbytes+1); |
|
434 test(strcmp(buf,*mp)==0); |
|
435 |
|
436 test_Next("Client send/recv"); |
|
437 |
|
438 /* send */ |
|
439 mp++; |
|
440 nbytes=strlen(*mp); |
|
441 err=send(fd1,*mp, nbytes+1,0); |
|
442 test_ok(err==nbytes+1); |
|
443 |
|
444 /* recv - get the first 2 bytes so that we know the buffer is full */ |
|
445 mp++; |
|
446 nbytes=strlen(*mp); |
|
447 err=recv(fd1,buf,2,0); |
|
448 test_ok(err==2); |
|
449 |
|
450 /* ioctl */ |
|
451 |
|
452 nbytes2=-1; |
|
453 err=ioctl(fd1,E32IONREAD,&nbytes2); |
|
454 test_ok(err==0); |
|
455 test(nbytes2==(nbytes+1-2)); |
|
456 |
|
457 nbytes2=E32SELECT_READ|E32SELECT_WRITE|E32SELECT_EXCEPT; |
|
458 err=ioctl(fd1,E32IOSELECT,&nbytes2); |
|
459 test_ok(err==0); |
|
460 test(nbytes2==(E32SELECT_READ|E32SELECT_WRITE)); |
|
461 |
|
462 nbytes2=E32SELECT_READ|E32SELECT_WRITE|E32SELECT_EXCEPT; |
|
463 err=async_ioctl(fd1,E32IOSELECT,&nbytes2,&status); |
|
464 test_ok(err==0); |
|
465 err=async_ioctl_completion(fd1,E32IOSELECT,&nbytes2,&status); |
|
466 test_ok(err==0); |
|
467 if (nbytes2!=(E32SELECT_READ|E32SELECT_WRITE)) |
|
468 { |
|
469 nbytes2=E32SELECT_READ|E32SELECT_WRITE|E32SELECT_EXCEPT; |
|
470 err=ioctl(fd1,E32IOSELECT,&nbytes2); |
|
471 test_ok(err==0); |
|
472 test(nbytes2==(E32SELECT_READ|E32SELECT_WRITE)); |
|
473 } |
|
474 |
|
475 /* recv - get the rest of the data */ |
|
476 for (i=2; i<nbytes+1; i++) |
|
477 { |
|
478 err=recv(fd1,buf+i,1,0); |
|
479 test_ok(err==1); |
|
480 } |
|
481 test(strcmp(buf,*mp)==0); |
|
482 |
|
483 /* ioctl again - this time there is no data pending */ |
|
484 nbytes2=-1; |
|
485 err=ioctl(fd1,E32IONREAD,&nbytes2); |
|
486 test_ok(err==0); |
|
487 test(nbytes2==0); |
|
488 |
|
489 nbytes2=E32SELECT_READ|E32SELECT_WRITE|E32SELECT_EXCEPT; |
|
490 err=ioctl(fd1,E32IOSELECT,&nbytes2); |
|
491 test_ok(err==0); |
|
492 test(nbytes2==E32SELECT_WRITE); |
|
493 |
|
494 nbytes2=E32SELECT_READ|E32SELECT_WRITE|E32SELECT_EXCEPT; |
|
495 err=async_ioctl(fd1,E32IOSELECT,&nbytes2,&status); |
|
496 test_ok(err==0); |
|
497 err=async_ioctl_completion(fd1,E32IOSELECT,&nbytes2,&status); |
|
498 test_ok(err==0); |
|
499 test(nbytes2==E32SELECT_WRITE); |
|
500 |
|
501 /* sendto */ |
|
502 mp++; |
|
503 nbytes=strlen(*mp); |
|
504 addrsize=sizeof(addr1); |
|
505 err=sendto(fd1, *mp, nbytes+1,0,(struct sockaddr*)&addr1,addrsize); |
|
506 test_errno(err<0,ENOSYS); |
|
507 err=send(fd1, *mp, nbytes+1,0); /* to keep synchronisation */ |
|
508 test_ok(err==nbytes+1); |
|
509 |
|
510 /* recvfrom */ |
|
511 mp++; |
|
512 nbytes=strlen(*mp); |
|
513 addrsize=sizeof(addr2); |
|
514 addr2.sin_port=0; |
|
515 err=recvfrom(fd1, buf, nbytes+1,0,(struct sockaddr*)&addr2,&addrsize); |
|
516 test_ok(err==nbytes+1); |
|
517 test(strcmp(buf,*mp)==0); |
|
518 test(addr2.sin_family==AF_INET); |
|
519 test(addr2.sin_port==htons(port)); |
|
520 test(addrsize<=sizeof(addr2)); |
|
521 |
|
522 /* another sendto */ |
|
523 test_Next("Client revcfrom with null fromaddr"); |
|
524 mp++; |
|
525 nbytes=strlen(*mp); |
|
526 addrsize=sizeof(addr1); |
|
527 err=sendto(fd1, *mp, nbytes+1,0,(struct sockaddr*)&addr1,addrsize); |
|
528 test_errno(err<0,ENOSYS); |
|
529 err=send(fd1, *mp, nbytes+1,0); /* to keep synchronisation */ |
|
530 test_ok(err==nbytes+1); |
|
531 |
|
532 /* recvfrom */ |
|
533 mp++; |
|
534 nbytes=strlen(*mp); |
|
535 addrsize=sizeof(addr2); |
|
536 memset(buf,0xFF,sizeof(buf)); |
|
537 err=recvfrom(fd1, buf, nbytes+1,0,0,0); //do a recvfrom with a null address |
|
538 test_ok(err==nbytes+1); |
|
539 test(strcmp(buf,*mp)==0); |
|
540 |
|
541 |
|
542 |
|
543 sleep(2); |
|
544 /* |
|
545 test_Next("Test half-closed connection"); |
|
546 |
|
547 // read from half-closed socket |
|
548 mp++; |
|
549 nbytes=strlen(*mp); |
|
550 err=read(fd1, buf, nbytes+1); |
|
551 test_errno(err<0, EPIPE); |
|
552 |
|
553 nbytes=strlen(*mp); |
|
554 err=write(fd1,*mp,nbytes+1); |
|
555 test_ok(err==nbytes+1); |
|
556 |
|
557 sleep(2); |
|
558 |
|
559 // read from a connection closed by the other end |
|
560 mp++; |
|
561 nbytes=strlen(*mp); |
|
562 err=read(fd1,buf,nbytes+1); |
|
563 test_errno(err<0, EPIPE); |
|
564 */ |
|
565 err=close(fd1); |
|
566 test_ok(err==0); |
|
567 |
|
568 // Large transmission - and another connection to the server socket |
|
569 |
|
570 test_Next("Test large transmission"); |
|
571 |
|
572 fd1=socket(AF_INET, SOCK_STREAM, 0); |
|
573 test_ok(fd1>=0); |
|
574 |
|
575 sleep(2); /* give server a chance to run */ |
|
576 |
|
577 addr1=testaddr; |
|
578 addr1.sin_port=htons(port); |
|
579 addrsize=sizeof(addr1); |
|
580 |
|
581 //this connect fails. Why is this? |
|
582 err=connect(fd1,(struct sockaddr*)&addr1,addrsize); |
|
583 test_ok(err==0); |
|
584 |
|
585 |
|
586 addrsize=sizeof(addr2); |
|
587 err=getpeername(fd1,(struct sockaddr*)&addr2,&addrsize); |
|
588 test_ok(err==0); |
|
589 test(addr2.sin_family==AF_INET); |
|
590 test(addr2.sin_port==htons(port)); |
|
591 test(addrsize<=sizeof(addr2)); |
|
592 |
|
593 addrsize=sizeof(addr2); |
|
594 err=getsockname(fd1,(struct sockaddr*)&addr2,&addrsize); |
|
595 test_ok(err==0); |
|
596 test(addr2.sin_family==AF_INET); |
|
597 test(addr2.sin_port!=htons(port)); |
|
598 test(addr2.sin_port!=0); |
|
599 test(addrsize<=sizeof(addr2)); |
|
600 |
|
601 nbytes=0; |
|
602 { |
|
603 int buf; |
|
604 char * p; |
|
605 |
|
606 do |
|
607 { |
|
608 buf=sizeof(randbuf)-nbytes; |
|
609 if (buf>4095) |
|
610 buf=4095; |
|
611 p = (char*)randbuf+nbytes; |
|
612 // err=read(fd1, p, buf); |
|
613 err=recv(fd1, p, buf, 0); |
|
614 if (err>0) |
|
615 nbytes+=err; |
|
616 } |
|
617 while (nbytes<sizeof(randbuf) && err>0); |
|
618 } |
|
619 |
|
620 printf("\nnbytes=%d, err=%d, errno=%d\n", nbytes, err, errno); |
|
621 |
|
622 test_ok(err==0); /* want a graceful EOF */ |
|
623 test(nbytes==sizeof(randbuf)-sizeof(int)); /* expect a smaller test data set */ |
|
624 test(randbuf[0]==4441302); |
|
625 srand(randbuf[0]); |
|
626 for (i=1; i<10000; i++) |
|
627 test(randbuf[i]==rand()); |
|
628 |
|
629 |
|
630 |
|
631 err=recv(fd1, (char*)randbuf, 1, 0); |
|
632 test_ok(err==0); |
|
633 |
|
634 err=close(fd1); |
|
635 test_ok(err==0); |
|
636 |
|
637 } |
|
638 |
|
639 int close_console=0; |
|
640 void testConnection() |
|
641 { |
|
642 int err; |
|
643 void* server; |
|
644 char buf[100]; |
|
645 |
|
646 sprintf(buf, "TISTREAM server %d", close_console); |
|
647 server=create_thread(testServer, buf); |
|
648 test(server!=0); |
|
649 start_thread(server); |
|
650 |
|
651 sleep(2); /* give the server a chance to get started */ |
|
652 testClient(); |
|
653 |
|
654 err=wait_for_thread(server); |
|
655 test(err==0); |
|
656 |
|
657 if (close_console) |
|
658 { |
|
659 test_Close(); |
|
660 close(0); |
|
661 close(1); |
|
662 close(2); |
|
663 } |
|
664 } |
|
665 |
|
666 int main(int argc, char *argv[]) |
|
667 { |
|
668 void* client; |
|
669 int err; |
|
670 |
|
671 test_Title("AF_INET Streams"); |
|
672 |
|
673 err=CommInit(0); /* ensure a workable comms environment */ |
|
674 test(err==0); |
|
675 |
|
676 IN_SET_LOOPBACK_ADDR(&testaddr); |
|
677 |
|
678 if (argc==1) |
|
679 { |
|
680 // Run the test(s) without a CPosixServer first |
|
681 testSimple(); |
|
682 port +=2; |
|
683 testConnection(); |
|
684 port +=2; |
|
685 } |
|
686 |
|
687 |
|
688 test_Next("Test gethostname"); |
|
689 { |
|
690 char * hname; |
|
691 hname = (char*)malloc(200); |
|
692 if (hname) |
|
693 { |
|
694 err = gethostname(hname, 200); |
|
695 |
|
696 if (err) |
|
697 printf("gethostname, err=%d, errno=%d\n", err, errno); |
|
698 else |
|
699 printf("host name is %s\n", hname); |
|
700 |
|
701 free(hname); } |
|
702 else |
|
703 printf("host name - malloc failure\n"); |
|
704 |
|
705 } |
|
706 |
|
707 test_Next("Do it again using the CPosixServer (for them, not me)"); |
|
708 close_console=1; |
|
709 |
|
710 start_posix_server(); /* calls SpawnPosixServer from C++ code */ |
|
711 |
|
712 |
|
713 client=create_thread(testSimple, "TISTREAM simple"); |
|
714 test(client!=0); |
|
715 start_thread(client); |
|
716 err=wait_for_thread(client); |
|
717 test(err==0); |
|
718 port +=2; |
|
719 |
|
720 client=create_thread(testConnection, "TISTREAM client"); |
|
721 test(client!=0); |
|
722 start_thread(client); |
|
723 err=wait_for_thread(client); |
|
724 test(err==0); |
|
725 |
|
726 test_Close(); |
|
727 return 0; |
|
728 } |