Noble Ape
The Central Directories of the Noble Ape Simulation.
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Macros
network.c
Go to the documentation of this file.
1 /****************************************************************
2 
3  network.c
4 
5  =============================================================
6 
7  Copyright 1996-2014 Tom Barbalet. All rights reserved.
8 
9  Permission is hereby granted, free of charge, to any person
10  obtaining a copy of this software and associated documentation
11  files (the "Software"), to deal in the Software without
12  restriction, including without limitation the rights to use,
13  copy, modify, merge, publish, distribute, sublicense, and/or
14  sell copies of the Software, and to permit persons to whom the
15  Software is furnished to do so, subject to the following
16  conditions:
17 
18  The above copyright notice and this permission notice shall be
19  included in all copies or substantial portions of the Software.
20 
21  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
22  EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
23  OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
24  NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
25  HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
26  WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
27  FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
28  OTHER DEALINGS IN THE SOFTWARE.
29 
30  This software and Noble Ape are a continuing work of Tom Barbalet,
31  begun on 13 June 1996. No apes or cats were harmed in the writing
32  of this software.
33 
34  ****************************************************************/
35 
40 #if 0
41 
42 #include "noble.h"
43 
44 #include <stdio.h> /* for printf() and fprintf() */
45 #include <sys/socket.h> /* for socket(), connect(), send(), and recv() */
46 #include <arpa/inet.h> /* for sockaddr_in and inet_addr() */
47 #include <stdlib.h> /* for atoi() and exit() */
48 #include <string.h> /* for memset() */
49 #include <unistd.h> /* for close() */
50 
51 /* this initially is stubbed and will be expended as developed */
52 
53 n_int network_open(n_string ip, n_byte2 port, n_c_int * network_connection)
54 {
55  struct sockaddr_in addr; /* Local address */
56  /* Create socket for incoming connections */
57  if ((*network_connection = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP)) < 0)
58  {
59  return SHOW_ERROR("Failed to set up socket");
60  }
61  /* Construct local address structure */
62  io_erase((n_byte *)&addr, sizeof(addr));
63  addr.sin_family = AF_INET; /* Internet address family */
64  if (ip)
65  {
66  addr.sin_addr.s_addr = inet_addr(ip); /* Server IP address */
67  }
68  else
69  {
70  addr.sin_addr.s_addr = htonl(INADDR_ANY); /* Any incoming interface */
71  }
72  addr.sin_port = htons(port); /* Local port */
73 
74  /* Bind to the local address */
75  if (bind(*network_connection, (struct sockaddr *) &addr, sizeof(addr)) < 0)
76  {
77  return SHOW_ERROR("Failed to set up bind");
78  }
79  return 0;
80 }
81 
82 #define MAXPENDING 5 /* Maximum outstanding connection requests */
83 
84 void DieWithError(n_string errorMessage)
85 {
86  perror(errorMessage);
87  exit(1);
88 }
89 
90 void HandleTCPClient(n_c_int clntSocket)
91 {
92  n_string_block echoBuffer; /* Buffer for echo string */
93  n_int recvMsgSize; /* Size of received message */
94 
95  /* Receive message from client */
96  if ((recvMsgSize = recv(clntSocket, echoBuffer, sizeof(n_constant_string), 0)) < 0)
97  DieWithError("recv() failed");
98 
99  /* Send received string and receive again until end of transmission */
100  while (recvMsgSize > 0) /* zero indicates end of transmission */
101  {
102  /* Echo message back to client */
103  if (send(clntSocket, echoBuffer, recvMsgSize, 0) != recvMsgSize)
104  DieWithError("send() failed");
105 
106  /* See if there is more data to receive */
107  if ((recvMsgSize = recv(clntSocket, echoBuffer, sizeof(n_constant_string), 0)) < 0)
108  DieWithError("recv() failed");
109  }
110  close(clntSocket); /* Close client socket */
111 }
112 
113 #ifdef EXAMPLE_SERVER
114 
115 int main(int argc, char *argv[])
116 {
117  int servSock; /* Socket descriptor for server */
118  int clntSock; /* Socket descriptor for client */
119  struct sockaddr_in echoServAddr; /* Local address */
120  struct sockaddr_in echoClntAddr; /* Client address */
121  unsigned short echoServPort; /* Server port */
122  unsigned int clntLen; /* Length of client address data structure */
123 
124  if (argc != 2) /* Test for correct number of arguments */
125  {
126  fprintf(stderr, "Usage: %s <Server Port>\n", argv[0]);
127  exit(1);
128  }
129 
130  echoServPort = atoi(argv[1]); /* First arg: local port */
131 
132  /* Create socket for incoming connections */
133  if ((servSock = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP)) < 0)
134  DieWithError("socket() failed");
135 
136  /* Construct local address structure */
137  memset(&echoServAddr, 0, sizeof(echoServAddr)); /* Zero out structure */
138  echoServAddr.sin_family = AF_INET; /* Internet address family */
139  echoServAddr.sin_addr.s_addr = htonl(INADDR_ANY); /* Any incoming interface */
140  echoServAddr.sin_port = htons(echoServPort); /* Local port */
141 
142  /* Bind to the local address */
143  if (bind(servSock, (struct sockaddr *) &echoServAddr, sizeof(echoServAddr)) < 0)
144  DieWithError("bind() failed");
145 
146  /* Mark the socket so it will listen for incoming connections */
147  if (listen(servSock, MAXPENDING) < 0)
148  DieWithError("listen() failed");
149 
150  for (;;) /* Run forever */
151  {
152  /* Set the size of the in-out parameter */
153  clntLen = sizeof(echoClntAddr);
154 
155  /* Wait for a client to connect */
156  if ((clntSock = accept(servSock, (struct sockaddr *) &echoClntAddr,
157  &clntLen)) < 0)
158  DieWithError("accept() failed");
159 
160  /* clntSock is connected to a client! */
161 
162  printf("Handling client %s\n", inet_ntoa(echoClntAddr.sin_addr));
163 
164  HandleTCPClient(clntSock);
165  }
166  /* NOT REACHED */
167 }
168 
169 #else
170 
171 int main(int argc, char *argv[])
172 {
173  int sock; /* Socket descriptor */
174  struct sockaddr_in echoServAddr; /* Echo server address */
175  unsigned short echoServPort; /* Echo server port */
176  char *servIP; /* Server IP address (dotted quad) */
177  char *echoString; /* String to send to echo server */
178  char echoBuffer[RCVBUFSIZE]; /* Buffer for echo string */
179  unsigned int echoStringLen; /* Length of string to echo */
180  int bytesRcvd, totalBytesRcvd; /* Bytes read in single recv()
181  and total bytes read */
182 
183  if ((argc < 3) || (argc > 4)) /* Test for correct number of arguments */
184  {
185  fprintf(stderr, "Usage: %s <Server IP> <Echo Word> [<Echo Port>]\n",
186  argv[0]);
187  exit(1);
188  }
189 
190  servIP = argv[1]; /* First arg: server IP address (dotted quad) */
191  echoString = argv[2]; /* Second arg: string to echo */
192 
193  if (argc == 4)
194  echoServPort = atoi(argv[3]); /* Use given port, if any */
195  else
196  echoServPort = 7; /* 7 is the well-known port for the echo service */
197 
198  /* Create a reliable, stream socket using TCP */
199  if ((sock = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP)) < 0)
200  DieWithError("socket() failed");
201 
202  /* Construct the server address structure */
203  memset(&echoServAddr, 0, sizeof(echoServAddr)); /* Zero out structure */
204  echoServAddr.sin_family = AF_INET; /* Internet address family */
205  echoServAddr.sin_addr.s_addr = inet_addr(servIP); /* Server IP address */
206  echoServAddr.sin_port = htons(echoServPort); /* Server port */
207 
208  /* Establish the connection to the echo server */
209  if (connect(sock, (struct sockaddr *) &echoServAddr, sizeof(echoServAddr)) < 0)
210  DieWithError("connect() failed");
211 
212  echoStringLen = strlen(echoString); /* Determine input length */
213 
214  /* Send the string to the server */
215  if (send(sock, echoString, echoStringLen, 0) != echoStringLen)
216  DieWithError("send() sent a different number of bytes than expected");
217 
218  /* Receive the same string back from the server */
219  totalBytesRcvd = 0;
220  printf("Received: "); /* Setup to print the echoed string */
221  while (totalBytesRcvd < echoStringLen)
222  {
223  /* Receive up to the buffer size (minus 1 to leave space for
224  a null terminator) bytes from the sender */
225  if ((bytesRcvd = recv(sock, echoBuffer, RCVBUFSIZE - 1, 0)) <= 0)
226  DieWithError("recv() failed or connection closed prematurely");
227  totalBytesRcvd += bytesRcvd; /* Keep tally of total bytes */
228  echoBuffer[bytesRcvd] = '\0'; /* Terminate the string! */
229  printf("%s", echoBuffer); /* Print the echo buffer */
230  }
231 
232  printf("\n"); /* Print a final linefeed */
233 
234  close(sock);
235  exit(0);
236 }
237 
238 #endif
239 
240 #endif