#1
  1. No Profile Picture
    Junior Member
    Devshed Newbie (0 - 499 posts)

    Join Date
    Apr 2003
    Location
    Chico, CA
    Posts
    14
    Rep Power
    0

    c tcp sockets question


    I'm confused about something. I've been reading tutorials on sockets and can't really understand what's going on behind the scenes when you use socket(), bind(), listen(), and accept(). Is a socket something that processes contend for?

    in the following example:
    ------------------------------------------------------------------------------------
    int main(void)
    {
    int sockfd, new_fd; // listen on sock_fd, new connection on new_fd
    struct sockaddr_in my_addr; // my address information
    struct sockaddr_in their_addr; // connector's address information
    int sin_size;
    struct sigaction sa;
    int yes=1;

    if ((sockfd = socket(AF_INET, SOCK_STREAM, 0)) == -1) {
    perror("socket");
    exit(1);
    }

    if (setsockopt(sockfd,SOL_SOCKET,SO_REUSEADDR,&yes,sizeof(int)) == -1) {
    perror("setsockopt");
    exit(1);
    }

    my_addr.sin_family = AF_INET; // host byte order
    my_addr.sin_port = htons(MYPORT); // short, network byte order
    my_addr.sin_addr.s_addr = INADDR_ANY; // automatically fill with my IP
    memset(&(my_addr.sin_zero), '\0', 8); // zero the rest of the struct

    if (bind(sockfd, (struct sockaddr *)&my_addr, sizeof(struct sockaddr))
    == -1) {
    perror("bind");
    exit(1);
    }

    if (listen(sockfd, BACKLOG) == -1) {
    perror("listen");
    exit(1);
    }

    sa.sa_handler = sigchld_handler; // reap all dead processes
    sigemptyset(&sa.sa_mask);
    sa.sa_flags = SA_RESTART;
    if (sigaction(SIGCHLD, &sa, NULL) == -1) {
    perror("sigaction");
    exit(1);
    }

    while(1) { // main accept() loop
    sin_size = sizeof(struct sockaddr_in);
    if ((new_fd = accept(sockfd, (struct sockaddr *)&their_addr,
    &sin_size)) == -1) {
    perror("accept");
    continue;
    }
    printf("server: got connection from %s\n",
    inet_ntoa(their_addr.sin_addr));
    if (!fork()) { // this is the child process
    close(sockfd); // child doesn't need the listener
    if (send(new_fd, "Hello, world!\n", 14, 0) == -1)
    perror("send");
    close(new_fd);
    exit(0);
    }
    close(new_fd); // parent doesn't need this
    }

    return 0;
    }
    ------------------------------------------------------------------------------------

    Are the children forked off after accept able to all communicate through the same port? I checked with netstat and the children are all connected on port MYPORT. It seems to me that accept creates a new connection associated with new_fd, that can function independently of other processes using the same port. But then I've looked at other examples using preforking where the parent process forks a bunch of children all trying to accept(), but these all block until the process previously doing accept() receives a connection, at which time another process doing accept "locks" the resource. This behavior seems contrary to what I've found with a non-preforking example, where the children all have their own file descriptors to the same socket(or at least the same port), but seem to be communicating independently.

    If anyone knows of a website where this kind of stuff is explained, that would be helpful.

    Greg
  2. #2
  3. not a fan of fascism (n00b)
    Devshed Frequenter (2500 - 2999 posts)

    Join Date
    Feb 2003
    Location
    ct
    Posts
    2,756
    Rep Power
    95
    What your observing its TCP's way of managing connections and assuring that every connection can be uniquely identified. TCP identifies a connection thu a process called de-multiplexing; it examines the 4-tuple of: source ip -port && destination ip - port. Together these 4 values UNIQUELY identify a connectio. So, this means that no two connections may contain the same values. This is why you are able to handle many clients thru the same port. Each client has a unique ip address. So this assures the 4tuple of (source ip/port&&dest ip/port) is unique. Now lets say the same client connects to you twice, how will they be identified uniquely? the clients tcp will choose a different port number the 2nd connection. So, lets say you have client A whose ip is 1.2.3.4. You have a server, ip 6.6.6.6 listening on port 50. The following could happen...
    A connects to you, the 4 tuple identifying this connect is 1.2.3.4/32000 -> 6.6.6.6->50 ; A then connects again, the 4 tuple is 1.2.3.4/32001 -> 6.6.6.6/50 and again 1.2.3.4/32002 -> 6.6.6.6/50 ... and so on.
    Now in ur second example where a bunch of clients first fork and then all try to accept. TCP only has 1 connection queue. SO even tho u could fork a thousand children all waiting to accept; only 1 may access the queue at a time. So, each process will block and then "lock" into accept. If you want to read a truly excellent and well written book(s); i advise TCP/IP Illustrated by W. Richard Stevens. It is truly worth its weight in gold( and its hardcover so its heavy!). Once you read that book and move on to the other 2 in the series u will understand tcp/ip very well.

    ps. yea i suck at explaining stuff, lol! get teh book u wont be dissapointed.

IMN logo majestic logo threadwatch logo seochat tools logo