/* tcp1-serv.c: illustrates an parallel TCP server */ #include #include #include #include #include #include #include #include #include #include #include int main(int argc, char *argv[]) { int s1; /* s1 = listen socket */ int s2; /* s2 = connect socket */ struct sockaddr_in me; /* My own Internet address */ struct sockaddr_in myname; /* Used to retrieve my TCP port */ int myname_len; struct sockaddr_in from; /* Internet address from client */ int len; /* length associated with `from' */ char c; /* Used to get data from connection */ if (argc == 1) { printf("Usage: %s port\n", argv[0]); exit(1); } /* --- Create a socket --- */ s1 = socket(AF_INET, SOCK_STREAM, 0); /* --- Set up my own Internet address to bind to the socket --- */ me.sin_family = AF_INET; /* Put in the family */ me.sin_port = htons(atoi(argv[1])); /* Put in the port number */ me.sin_addr.s_addr = htonl(INADDR_ANY); /* Use wildcard address */ /* --- Here goes the binding... --- */ if (bind(s1, (struct sockaddr *) &me, sizeof(me) ) < 0) { perror("bind:"); exit(1); } /* --- Just for curiousity sake, let's find out the name of the socket... --- */ myname_len = sizeof(myname); if (getsockname(s1, (struct sockaddr *) &myname, &myname_len) == -1) { printf("Trouble: system did not find my socket...\n"); exit(1); } printf("Server's listen socket is binded to:\n"); printf(" myname.sin_family = %u (should be AF_INET = %u)\n", myname.sin_family, AF_INET); printf(" myname.sin_addr.s_addr = %u\n", myname.sin_addr.s_addr); printf(" myname.sin_port = %u\n", myname.sin_port); /* --- Specify the maximum number of `backlogged' connection requests --- */ listen(s1, 5); /* --- After making our socket public, the server wait for connection requests --- */ while (1) { /* --- Wait (i.e., block) until someone makes a connect call to my s1 socket NOTE: accept RETURNS a socket descriptor similar to the socket() call BUT a huge difference is accept aslo did a bind to it without asking your permission --- */ printf("Ready to accept a new call.....\n"); len = sizeof(from); if ( (s2 = accept(s1, (struct sockaddr *) &from, &len)) < 0) { perror("accept: "); exit(1); } printf("\n\nNew call accepted.....\n\n"); printf("**** Information about this call:\n"); /* --------------------------------------- Print info of the listen socket --------------------------------------- */ myname_len = sizeof(myname); getsockname(s1, (struct sockaddr *) &myname, &myname_len); printf("The listen socket is:\n"); printf(" sin_addr.s_addr = %u\n", myname.sin_addr.s_addr); printf(" sin_port = %u\n\n", myname.sin_port); /* --------------------------------------- Print info of the data socket --------------------------------------- */ myname_len = sizeof(myname); getsockname(s2, (struct sockaddr *) &myname, &myname_len); printf("The TCP connection is:\n"); printf("========================\n"); printf("My network address:\n"); printf(" sin_addr.s_addr = %u\n", myname.sin_addr.s_addr); printf(" sin_port = %u\n", myname.sin_port); /* ------------------------------------------- Print info of peer socket ------------------------------------------- */ myname_len = sizeof(myname); getpeername(s2, (struct sockaddr *) &myname, &myname_len); printf("The peer socket (client) network address:\n"); printf(" sin_addr.s_addr = %u\n", myname.sin_addr.s_addr); printf(" sin_port = %u\n\n", myname.sin_port); printf("\n\nNow forking a child...\n"); /* --------------------- fork() --------------------- */ if ( fork() == 0 ) { /* =============================== Child process ================================ */ close(s1); // Listen socket /* ========================================= Use data socket and comm. with client ========================================= */ while (read(s2, &c, 1) > 0) { putchar(c); fflush(stdout); } close(s2); printf("\n\n...Done...\n\n"); exit(0); } else { close(s2); } } }