/* constants */
+#define BACKLOG 5
#define BUFFER_SIZE 4096
+#define TIMEOUT 100000
/* macros */
VERBOSE (DEBUG, fprintf (stdout, "Binding socket\n"));
int rc = bind (sock, (struct sockaddr *)&addr, sizeof (addr));
if (rc == SOCKET_ERROR) {
- VERBOSE (ERROR, fprintf (stderr, "error: %d\n", ERRNO));
+ VERBOSE (ERROR, fprintf (stderr, "error: bind %d\n", ERRNO));
rc = closesocket (sock);
if (rc == SOCKET_ERROR) {
- VERBOSE (ERROR, fprintf (stderr, "error: %d\n", ERRNO));
+ VERBOSE (ERROR, fprintf (stderr, "error: close %d\n", ERRNO));
}
return -1;
}
int val = 1;
rc = setsockopt (sock, IPPROTO_TCP, TCP_NODELAY, (char *)&val, sizeof (val));
if (rc < 0) {
- VERBOSE (ERROR, fprintf (stderr, "%s\n", "setsockopt/TCP_NODELAY"));
+ VERBOSE (ERROR, fprintf (stderr, "error: %s\n", "setsockopt/TCP_NODELAY"));
closesocket (sock);
if (rc == SOCKET_ERROR) {
- VERBOSE (ERROR, fprintf (stderr, "error: %d\n", ERRNO));
+ VERBOSE (ERROR, fprintf (stderr, "error: close %d\n", ERRNO));
+ }
+ return -1;
+ }
+
+ rc = listen (sock, BACKLOG);
+ if (rc < 0) {
+ VERBOSE (ERROR, fprintf (stderr, "error: %s\n", "listen"));
+ closesocket (sock);
+ if (rc == SOCKET_ERROR) {
+ VERBOSE (ERROR, fprintf (stderr, "error: close %d\n", ERRNO));
}
return -1;
}
#endif
}
-/* vim: set ts=4 sw=4 et: */
+/* accept incomming connection */
+
+int accept_incoming_connection (socket_t sock)
+{
+ int connection = accept (sock, NULL, 0);
+ if (connection < 0) {
+ return connection;
+ }
+
+#ifndef _WIN32 /* POSIX */
+ fcntl (connection, F_SETFL, O_NONBLOCK);
+#endif
+ int val = 1;
+ rc = setsockopt (connection, IPPROTO_TCP, TCP_NODELAY, (char *)&val, sizeof (val));
+ if (rc < 0) {
+ VERBOSE (ERROR, fprintf (stderr, "error: %s\n", "setsockopt/TCP_NODELAY"));
+ closesocket (connection);
+ if (rc == SOCKET_ERROR) {
+ VERBOSE (ERROR, fprintf (stderr, "error: close %d\n", ERRNO));
+ }
+ return -1;
+ }
+
+ return connection;
+}
+
+/* receive data */
+int receive_data (socket_t sock, unsigned char data, int maxlen)
+{
+
+ /* timeout management */
+ fd_set rfds;
+ struct timeval tv = { 0, TIMEOUT };
+ FD_ZERO (&rfds);
+ FD_SET (sock, &rfds);
+
+ int retval = select (sock + 1, &rfds, NULL, NULL, &tv);
+ if (retval != 1)
+ return retval; /* 0 or SOCKET_ERROR */
+
+ /* read from socket */
+ int len = read (sock, data, maxlen);
+
+ if (rc = 0) { /* sock closed */
+ return 0;
+ } else if ((rc < 0) && (ERRNO != EAGAIN)) { /* error */
+ return -1;
+ } else if (rc > 0) {
+ return len;
+ }
+
+ /* do we retry ? */
+
+ return -2;
+}
+
/* vim: set ts=4 sw=4 et: */
VERBOSE (ERROR, fprintf (stderr, "Can't open listening socket\n"));
return 1;
}
-
VERBOSE (INFO, fprintf (stdout, "Listening socket on port %d\n", port));
- sleep (20);
+
+ /* main loop */
+ while (1) {
+ int connection = accept_incoming_connection (sock);
+ if ((connection < 0) && (errno == EAGAIN)) {
+ accept_nonblock_ok = 1;
+ }
+ if (connection < 0) {
+ sleep (1);
+ continue;
+ }
+
+ VERBOSE (DEBUG, fprintf (stdout, "Server connected, waiting for data\n"));
+
+ while (1) {
+ unsigned char data[BUFFER_SIZE] = {0};
+ int len = 0;
+
+ len = receive_data (connection, data, size (data));
+ if (len == 0) {
+ // nonblocking connection
+ sleep (1);
+ continue;
+ }
+ if (len < 0) {
+ VERBOSE (WARNING, fprintf (stdout, "Connection closed by peer\n"));
+ close_connection (connection);
+ break;
+ }
+
+ // processing
+
+ len = send_data (connection, data, size (data));
+ if (len < 0) {
+ VERBOSE (WARNING, fprintf (stdout, "Connection closed by peer\n"));
+ close_connection (connection);
+ break;
+ }
+
+ /* sleep so that we go trhough remaining data in receive buffer */
+ usleep (1e5);
+ }
+ }
VERBOSE (DEBUG, fprintf (stdout, "Closing socket\n"));
close_listening_socket (sock);