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
intrepresent sockets, usessocketinstead,uint_ptr. when checking invalid socket handle, don't use< 0, use== invalid_socketinstead.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_reuseaddrexpectsboolvalue, notcharvalue.booltypedefint, 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
Post a Comment