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

    Join Date
    Jul 2003
    Posts
    26
    Rep Power
    0

    More WinSock help!


    Alright, I slapped together a two programs today. One that just connects to my IP and recv()'s untill the connection dissapears, and then it closes, I gave this to my friend. Then I wrote the obvious counterpart to it. When I run my mine it just says "Checking for connection" and nothing else. When I close it though my friend program ends, so it has to have connected. Can someone give me a suitable condition for the marked while loop.

    PHP Code:
        cout<<"Checking for connection"<<endl;
        
        while(*
    condition*)
        {
            
    listen(sockfd5);
            
    int sin_size=sizeof(struct sockaddr_in);
            
    new_fd=accept(sockfd, (struct sockaddr *)&dest_addr, &sin_size);
        }
        
    cout<<"Connection recieved"<<endl;

        while(
    1)
        {
            
    len=strlen(msg);
            
    bytes_sent=send(new_fd,msg,len,0);
            
    cout<<len<<" "<<bytes_sent<<endl;
        } 
  2. #2
  3. Contributing User
    Devshed Supreme Being (6500+ posts)

    Join Date
    Jan 2003
    Location
    USA
    Posts
    7,163
    Rep Power
    2222
    Call listen only once, before you enter the while loop.

    I'm not sure that that while loop is necessary. accept will block until a client connects.
  4. #3
  5. No Profile Picture
    Junior Member
    Devshed Newbie (0 - 499 posts)

    Join Date
    Jul 2003
    Posts
    26
    Rep Power
    0
    I was starting to suspect that ^_^; Thanks!
  6. #4
  7. No Profile Picture
    Junior Member
    Devshed Newbie (0 - 499 posts)

    Join Date
    Jul 2003
    Posts
    26
    Rep Power
    0
    Do I need to bind new_fd with dest_addr?
  8. #5
  9. Contributing User
    Devshed Supreme Being (6500+ posts)

    Join Date
    Jan 2003
    Location
    USA
    Posts
    7,163
    Rep Power
    2222
    Even I have been known to get confused about the use of listen if I haven't written a server for a while.

    BTW, I trust that you are aware that you can run both the server and the client on the same system, so you shouldn't need to have two machines involved in every level of development and testing. Have the server bind to the listening port and have the client connect to that port on localhost (127.0.0.1).

    The only time I couldn't do it on one machine was when I ran a broadcast time server for a broadcast client. The broadcast client has to bind to the well-known port (timserver on port 37), which kept the server from sending on that port. But other than this one case, I haven't had any problem connecting to localhost.

    Also, there is a file on your system that lists the well-known services and their associated ports. The file is called services and Win2k keeps it in the C:\WINNT\system32\drivers\etc directory. I assume that XP does the same.
  10. #6
  11. Contributing User
    Devshed Supreme Being (6500+ posts)

    Join Date
    Jan 2003
    Location
    USA
    Posts
    7,163
    Rep Power
    2222
    Originally posted by Kyro
    Do I need to bind new_fd with dest_addr?
    No, that is done automatically by accept. When accept returns, dest_addr contains the sockaddr_in of the client whose connection you just accepted. You should include that information in your "Connection recieved" output. BTW, that is how a server knows the address of who has connected to it.

    The inet_ntoa function will convert the 32-bit binary address to a dotted-decimal string, the inverse of inet_addr -- no need to apply ntohl.

    Also, if you are going to allow multiple simultaneous client connections, then you will need to make sure that you don't overwrite the earlier clients' "new_fd" from the newer clients'.
    Last edited by dwise1_aol; July 11th, 2003 at 12:58 AM.
  12. #7
  13. No Profile Picture
    Junior Member
    Devshed Newbie (0 - 499 posts)

    Join Date
    Jul 2003
    Posts
    26
    Rep Power
    0
    When I build and compile the following code, it connects to the other computer, and then trys to send and it will cout "3 -1 10054", which is:"Connection reset by peer.
    An existing connection was forcibly closed by the remote host. This normally results if the peer application on the remote host is suddenly stopped, the host is rebooted, the host or remote network interface is disabled, or the remote host uses a hard close (see setsockopt for more information on the SO_LINGER option on the remote socket). This error may also result if a connection was broken due to keep-alive activity detecting a failure while one or more operations are in progress. Operations that were in progress fail with WSAENETRESET. Subsequent operations fail with WSAECONNRESET. "

    Any help?


    PHP Code:
    #include <iostream.h>
    #include <winsock2.h>

    void main()
    {
        
    WSADATA wsaData;
        if (
    WSAStartup(MAKEWORD(20), &wsaData) != 0)
        {
            
    cout<<"WSAStartup failed."<<endl;
            exit(
    1);
        }
        
    char *msg="Hey";
        
    int lenbytes_sent;

        
    SOCKET sockfdnew_fd;//creates an int to hold the file descriptor for the socket
        
    struct sockaddr_in my_addrdest_addr;//creates socket struct

        
    sockfd=socket(AF_INET,SOCK_STREAM,0);//put a file descriptor into sockfd 

        
    memset(&dest_addr0sizeof(dest_addr));

        
    memset(&my_addr0sizeof(my_addr));//sets the struct to 0
        
    my_addr.sin_family=AF_INET;//sets socket struct to the internet
        
    my_addr.sin_port=htons(6000);//sets socket to a port (0 uses a random port)
        
    my_addr.sin_addr.s_addr=INADDR_ANY;//sets socket to my IP
        
        
    bind(sockfd, (struct sockaddr *)&my_addrsizeof(struct sockaddr));

        
    cout<<"Checking for connection"<<endl;

        
    int sin_size=sizeof(struct sockaddr_in);

        
    listen(sockfd5);
        
    new_fd=accept(sockfd, (struct sockaddr *)&dest_addr, &sin_size);
      
        
    cout<<"Connection recieved"<<endl;

        while(
    1)
        {
            
    len=strlen(msg);
            
    bytes_sent=send(new_fd,msg,len,0);
            
    cout<<len<<" "<<bytes_sent<<WSAGetLastError()<<endl;
        }

  14. #8
  15. Contributing User
    Devshed Supreme Being (6500+ posts)

    Join Date
    Jan 2003
    Location
    USA
    Posts
    7,163
    Rep Power
    2222
    How does the client work? The server repeatedly sends the message to the client. What does the client do when it receives the message?
  16. #9
  17. No Profile Picture
    Junior Member
    Devshed Newbie (0 - 499 posts)

    Join Date
    Jul 2003
    Posts
    26
    Rep Power
    0
    The client connects then goes into a while loop that recieves untill the connection is closed. When the client gets the message it cout<<'s it
  18. #10
  19. Contributing User
    Devshed Supreme Being (6500+ posts)

    Join Date
    Jan 2003
    Location
    USA
    Posts
    7,163
    Rep Power
    2222
    So from my reading, after connecting/accepting both the server and client go into infinite loops with the server constantly sending and the client constantly reading and neither of them taking any explicit action to close the connection.

    Try this in the server (very roughly sketched):
    Code:
    listen
    while (1)  // should never exit, but rather serve one client after another
    {
        new_sock = accept
        printf("Handling client %s\n", inet_ntoa(ClntAddr.sin_addr));
        send msg to new_sock
    
        closesocket(new_sock);    /* Close client socket */
    
    }
    Please pardon me for getting ahead here, but you should note that this will service only one client at a time. To serve multiple clients under Windows, you should use either the select function or multi-threading (creating a new thread for each client being serviced). You can find Winsock examples for both at http://cs.baylor.edu/~donahoo/PocketSocket/winsock.html .
  20. #11
  21. No Profile Picture
    Junior Member
    Devshed Newbie (0 - 499 posts)

    Join Date
    Jul 2003
    Posts
    26
    Rep Power
    0
    So even if I'm only trying to service one account (currently) I should use a loop like that?
  22. #12
  23. Contributing User
    Devshed Supreme Being (6500+ posts)

    Join Date
    Jan 2003
    Location
    USA
    Posts
    7,163
    Rep Power
    2222
    Originally posted by Kyro
    So even if I'm only trying to service one account (currently) I should use a loop like that?
    Well, of course every program should be written to do what it's designed to do. In a special test case, you could have a single-shot server that terminates as soon as it has serviced a single client. But normally a server starts up when the system does and continues to run as long as the system is running. The advantage to doing your testing with the server looping is that you can run multiple tests of the client without having to restart the server each time.

    Also, if the server and client try to race each other to shut down, it might cause one of them to appear to hang/freeze up. There are some issues in shutting down a connection that can come up. I would want to keep one end stable while terminating the other.
  24. #13
  25. No Profile Picture
    Junior Member
    Devshed Newbie (0 - 499 posts)

    Join Date
    Jul 2003
    Posts
    26
    Rep Power
    0
    Thanks

IMN logo majestic logo threadwatch logo seochat tools logo