2
* Copyright (C) 2002-2005 Novell/SUSE
4
* This program is free software; you can redistribute it and/or
5
* modify it under the terms of the GNU General Public License as
6
* published by the Free Software Foundation, version 2 of the
10
/* Basic tcp networking test. */
17
#include <netinet/in.h>
18
#include <netinet/tcp.h>
19
#include <sys/select.h>
20
#include <sys/socket.h>
22
#include <sys/types.h>
24
#include <arpa/inet.h>
27
#define HOSTIP "127.0.0.1"
30
#define WAITLEN 1 /* number of seconds for select to wait */
31
#define DATASOURCE "/dev/urandom"
35
/* server_bind_address returns the socket filedescriptor */
37
server_bind_address (int port) {
39
struct sockaddr_in serv_addr;
43
if ((sockfd = socket (PF_INET, SOCK_STREAM, 0)) < 0) {
44
perror ("FAIL: Server: can't open stream socket");
48
/* don't use SO_REUSEADDR in production code. */
49
setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, &value, sizeof(value));
51
memset(&serv_addr, 0UL, sizeof(serv_addr));
52
serv_addr.sin_family = AF_INET;
53
inet_pton (AF_INET, HOSTIP, &serv_addr.sin_addr);
54
serv_addr.sin_port = htons(port);
56
if (bind (sockfd, (struct sockaddr *) &serv_addr, sizeof (serv_addr)) != 0) {
57
perror("FAIL: Server: can't bind socket");
67
int my_select_read (int fd, int secs) {
76
retval = select (fd + 1, &rfds, NULL, NULL, &tv);
77
if ((retval == -1) || !(FD_ISSET(fd, &rfds))) {
84
int my_select_write (int fd, int secs) {
93
retval = select (fd + 1, NULL, &wfds, NULL, &tv);
94
if ((retval == -1) || !(FD_ISSET(fd, &wfds))) {
102
do_server (int sockfd) {
105
struct sockaddr_in cli_addr;
107
char buffer[BUFSIZE];
109
/* socket should already have listen() called on it by now */
110
retval = my_select_read (sockfd, WAITLEN);
112
perror ("FAIL: Server: select failed");
116
clilen = sizeof (cli_addr);
117
newsockfd = accept (sockfd, (struct sockaddr *) &cli_addr, &clilen);
120
perror ("FAIL: Server: can't accept socket");
125
retval = my_select_read (newsockfd, WAITLEN);
127
perror ("FAIL: Server: select failed");
131
len = recv (newsockfd, buffer, sizeof(buffer), 0);
133
perror ("FAIL: Server: read failed");
138
/* verify data received from the client */
139
if (memcmp((void *) buffer, (void *) data, sizeof(buffer)) != 0) {
140
fprintf(stderr, "FAIL: Server: memory comparison failed\n");
145
/* send the data back to the client */
146
if (send(newsockfd, data, sizeof(buffer), 0) < sizeof(buffer)) {
147
perror("FAIL: Server: problem sending data");
153
if (newsockfd >= 0) {
162
do_client (int port) {
164
struct sockaddr_in serv_addr;
166
char buffer[BUFSIZE];
168
/* create a socket */
169
if ((sockfd = socket(PF_INET, SOCK_STREAM, 0)) < 0) {
170
perror("FAIL: Client: can't open stream socket");
175
/* Set to non_block. */
176
fcntl(sockfd, F_SETFL, O_NONBLOCK);
177
//setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, &value, sizeof(value));
179
memset(&serv_addr, 0UL, sizeof(serv_addr));
180
serv_addr.sin_family = AF_INET;
181
inet_pton(AF_INET, HOSTIP, &serv_addr.sin_addr);
182
serv_addr.sin_port = htons(port);
184
if (connect(sockfd, (struct sockaddr *) &serv_addr, sizeof(serv_addr)) != 0) {
185
if (errno != EINPROGRESS) {
186
perror("FAIL: Client: can't connect to socket");
192
retval = my_select_write (sockfd, WAITLEN);
194
perror ("FAIL: Client: select failed");
198
/* send the data to the server */
199
if (send(sockfd, data, sizeof(buffer), 0) < sizeof(buffer)) {
200
perror("FAIL: Client: problem sending data");
205
retval = my_select_read (sockfd, WAITLEN);
207
perror ("FAIL: Client: select failed");
211
len = recv (sockfd, buffer, sizeof(buffer), 0);
213
perror ("FAIL: Client: read failed");
218
/* verify the data returned from the server */
219
if (memcmp((void *) buffer, (void *) data, sizeof(buffer)) != 0) {
220
fprintf(stderr, "FAIL: Client: memory comparison failed\n");
227
if (sockfd >= 0) close(sockfd);
232
main (int argc, char * argv[]) {
234
int fd, retval, waitstatus;
236
int serv_port = HOSTPORT;
238
fd = open(DATASOURCE, O_RDONLY);
240
perror("FAIL: open()ing data source failed");
244
if ((retval = read(fd, data, sizeof(data))) < sizeof(data)) {
245
perror("FAIL: problem reading data source");
252
serv_port = strtol(argv[1], NULL, 10);
255
/* get the server to listen, so the child has something to
256
* connect to if it wins the race. */
257
if ((sockfd = server_bind_address(serv_port)) < 0) {
261
if ((childpid = fork()) < 0) {
262
perror("FAIL: fork() failed");
267
return do_client (serv_port);
274
if ((WIFEXITED(waitstatus) != 0) && (WEXITSTATUS(waitstatus) == 0)) {