c - Winsock echo server port -


i'm trying port simple tcp echo program (https://github.com/mafintosh/echo-servers.c/blob/master/tcp-echo-server.c) under windows teaching purposes. adaptation compiles , run, doesn't work:

**** edit: listen call somehow cut out. thank remy ****

the client connects, doen't echo.

ported code follows (error messages in italian, should clear nevertheless):

#include <stdio.h> #include <stdlib.h> #include <winsock.h>  #define buffer_size 1024 void on_error(char *s) { fprintf(stderr,"%s\n",s); fflush(stderr); exit(1); }  int main(int argc, char *argv[]) {     wsadata wsadata;      int server_fd, client_fd, err;     struct sockaddr_in server, client;     char buf[buffer_size];      int port = 6666;      int risultato = wsastartup(makeword(2,2),&wsadata);     if (risultato != no_error)         {fprintf(stderr,"errore in wsastartup");fflush(stderr); exit(1);}      server_fd = socket(af_inet, sock_stream, 0);     if (server_fd < 0) on_error("non ho potuto creare il socket\n");         server.sin_family = af_inet;      server.sin_port = htons(port);      server.sin_addr.s_addr = htonl(inaddr_any);       const char opt_val = 1;     setsockopt(server_fd, sol_socket, so_reuseaddr, &opt_val, sizeof opt_val);     /** bind & listen **/     err = bind(server_fd, (struct sockaddr *) &server, sizeof(server));     if (err < 0) on_error("non ho potuto fare il bind del socket\n");        err = listen(server_fd, 128);     if (err < 0) on_error("non ho potuto mettermi in ascolto sul socket\n");     printf("server listening on port %d\n", port);      while (1) {       int client_len = sizeof(client);       {       client_fd = accept(server_fd, (struct sockaddr *) &client, &client_len);       } while ( client_fd = socket_error);        if (client_fd < 0) on_error("non riesco stabilire una nuova connessione\n");        while (1) {         int read = recv(client_fd, buf, buffer_size, 0);          if (!read) break;         if (read < 0) on_error("errore nella lettura dal client\n");          err = send(client_fd, buf, read, 0);         if (err < 0) on_error("errore nella scrittura verso il client\n");     }   }      wsacleanup();     return 0; } 

you calling bind() set listening port, not calling listen() start listening on port before entering accept() loop.

once fix mistake, accept() loop broken anyway because forcing client_fd socket_error if accept() successful. while() condition using = assignment operator when needs use == comparison operator instead. , should checking invalid_socket instead of socket_error.

now said, there other things consider:

  • winsock not use int represent sockets, uses socket instead, uint_ptr. when checking invalid socket handle, don't use < 0, use == invalid_socket instead.

  • most socket functions return error codes via wsagetlasterror() (wsastartup() being exception that). in habit of using it, , reporting error codes in output messages, know why things failing.

  • so_reuseaddr expects bool value, not char value. bool typedef int , 4 bytes.

  • not socket errors fatal, should not kill entire server if recv()/send() operation fails on non-fatal error.

  • send() not guaranteed send ask send, should account that.

  • don't forget close accepted client socket when done using it.

try this:

#include <stdio.h> #include <stdlib.h> #include <winsock.h>  #define buffer_size 1024  void on_error(char *s, int *errcode = null) {     int err = (errcode) ? *errcode : wsagetlasterror();     fprintf(stderr, "%s: %d\n", s, err);     fflush(stderr);     exit(1); }  int main(int argc, char *argv[]) {     wsadata wsadata;      socket server_fd, client_fd;     struct sockaddr_in server, client;     int port = 6666, err;      char buf[buffer_size];      err = wsastartup(makeword(2,2), &wsadata);     if (err != 0)         on_error("errore in wsastartup", &err);      server_fd = socket(af_inet, sock_stream, 0);     if (server_fd == invalid_socket)         on_error("non ho potuto creare il socket");      memset(&server, 0, sizeof(server));      server.sin_family = af_inet;      server.sin_port = htons(port);      server.sin_addr.s_addr = inaddr_any;       /** bind & listen **/     const bool opt_val = true;     setsockopt(server_fd, sol_socket, so_reuseaddr, (char*)&opt_val, sizeof(opt_val));     err = bind(server_fd, (struct sockaddr *) &server, sizeof(server));     if (err == socket_error)         on_error("non ho potuto fare il bind del socket");     err = listen(server_fd, 1);     if (err == socket_error)         on_error("non ho potuto mettermi in ascolto sul socket");      printf("server listening on port %d\n", port);      while (1)     {         int client_len = sizeof(client);         client_fd = accept(server_fd, (struct sockaddr *) &client, &client_len);          if (client_fd == invalid_socket)             on_error("non riesco stabilire una nuova connessione");          bool keeplooping = true;                 {             int read = recv(client_fd, buf, buffer_size, 0);              if (read == 0)                 break;              if (read == socket_error)             {                 err = wsagetlasterror();                 if ((err != wsaenotconn) && (err != wsaeconnaborted) && (err == wsaeconnreset))                     on_error("errore nella lettura dal client", &err);                 break;             }              char *pbuf = buf;                         {                 int sent = send(client_fd, pbuf, read, 0);                 if (sent == socket_error)                 {                     err = wsagetlasterror();                     if ((err != wsaenotconn) && (err != wsaeconnaborted) && (err == wsaeconnreset))                         on_error("errore nella scrittura verso il client", &err);                      keeplooping = false;                     break;                 }                  pbuf += sent;                 read -= sent;             }             while (read > 0);         }         while (keeplooping);          closesocket(client_fd);     }      wsacleanup();     return 0; } 

Comments