Academic Integrity: tutoring, explanations, and feedback — we don’t complete graded work or submit on a student’s behalf.

I\'ve done some research and it seems my issue is that the server accepts only o

ID: 3686446 • Letter: I

Question

I've done some research and it seems my issue is that the server accepts only one client during its lifetime and the test class starts the server only once for all test methods in the test class. So I need to set the accept() in a loop. But I'm not sure how to do that.

Here is my code so far:

import java.io.IOException;
import java.io.PrintWriter;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.Scanner;

public class GuessingServer {
   public static void main(String[] args) {
       try {
           ServerSocket server;

           server = new ServerSocket(5150);
           System.out.println("awaiting client...");
           Socket client = server.accept();
           System.out.println("client connected");
           Scanner in = new Scanner(client.getInputStream());
           PrintWriter out = new PrintWriter(client.getOutputStream(), true);
           String first = in.next();
           int high = in.nextInt();
           int low = Integer.parseInt(first);

           boolean serverRun = true;

           while (serverRun == true) {
               if (!first.equals("SHUT DOWN")) {
                   System.out.println(low);
                   System.out.println(high);

                   int bNum = ((high - low) / 2) + low;
                   out.println(bNum);
                   System.out.println(bNum);
                   String temp = in.next();

                   if (temp.equals("high")) {
                       high = bNum;
                       System.out.println(temp + ": ");
                       System.out.println(high);

                      
                   } else if (temp.equals("low")) {
                       low = bNum;
                       System.out.println(temp + ": ");
                       System.out.println(low);
                  
                   } else if (temp.equals("won")) {
                       System.out.println(temp);
                       serverRun = false;
                   } else if (temp.equals("lost")) {

                       System.out.println(temp);
                       serverRun = false;
                   }
               } else {
                   serverRun = false;
               }
           }
           client.close();
           in.close();
           out.close();
           server.close();
       } catch (IOException e) {
       }
   }
}

And here is the test bench:

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;

import java.io.IOException;
import java.io.PrintWriter;
import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
import java.net.Socket;
import java.util.NoSuchElementException;
import java.util.Random;
import java.util.Scanner;

import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.FixMethodOrder;
import org.junit.Test;
import org.junit.runners.MethodSorters;

@FixMethodOrder(MethodSorters.NAME_ASCENDING)
public class GuessingServerTest {
   @Test
   public void testReflection() {
       Class<?> iClass = GuessingServer.class;
       Field[] iFields = iClass.getDeclaredFields();

       for (Field f : iFields) {
           if (!f.isSynthetic()) {
               assertTrue ( "Field ""+f.getName()+"" should be private", Modifier.isPrivate( f.getModifiers() ));
               assertFalse( "Field ""+f.getName()+"" can't be static", Modifier.isStatic ( f.getModifiers() ));
           }
       }
   }

   @BeforeClass
   public static void startServer() {
       // run server
       Thread thread = new Thread(new Runnable() {
           @Override
           public void run() {
               GuessingServer.main( new String[]{ } );
           }
       });
       thread.start();
   }
   @Before
   public void waitTwoSecondsBetweenTests() {
       try {
           Thread.sleep( 2000 );
       }
       catch (InterruptedException e) {
           e.printStackTrace();
       }
   }

   @Test(timeout=3000)
   public void testA_WinningAfter1Try() {
       try {
           // run client
           Socket socket = new Socket( "localhost", 5150 );
           Scanner scanner = new Scanner ( socket.getInputStream() );
           PrintWriter writer = new PrintWriter( socket.getOutputStream(), true );
          
           writer.println( "101 401" );
           // try 1
           int actual = scanner.nextInt();
           assertEquals( "Incorrect result", 251, actual );

           writer.println( "won" );
          
           socket .close();
           scanner.close();
       }
       catch (IOException e) {
           e.printStackTrace();
           fail( "Error opening client socket" );
       }
       catch (NoSuchElementException e) {
           e.printStackTrace();
           fail( "The server didn't return a value" );
       }
   }

   @Test(timeout=3000)
   public void testB_WinningAfter2Tries() {
       try {
           // run client
           Socket socket = new Socket( "localhost", 5150 );
           Scanner scanner = new Scanner ( socket.getInputStream() );
           PrintWriter writer = new PrintWriter( socket.getOutputStream(), true );
          
           writer.println( "37 337" );
           // try 1
           int actual = scanner.nextInt();
           assertEquals( "Incorrect result", 187, actual );
           writer.println( "low" );
           // try 2
           actual = scanner.nextInt();
           assertEquals( "Incorrect result", 262, actual );
           writer.println( "high" );
           // try 3
           actual = scanner.nextInt();
           assertEquals( "Incorrect result", 224, actual );
           writer.println( "high" );
           // try 4
           actual = scanner.nextInt();
           assertEquals( "Incorrect result", 205, actual );
           writer.println( "low" );
           // try 5
           actual = scanner.nextInt();
           assertEquals( "Incorrect result", 214, actual );
           writer.println( "high" );
           // try 6
           actual = scanner.nextInt();
           assertEquals( "Incorrect result", 209, actual );
           writer.println( "high" );
           // try 7
           actual = scanner.nextInt();
           assertEquals( "Incorrect result", 207, actual );
           writer.println( "high" );
           // try 8
           actual = scanner.nextInt();
           assertEquals( "Incorrect result", 206, actual );
           writer.println( "won" );
          
           socket .close();
           scanner.close();
       }
       catch (IOException e) {
           e.printStackTrace();
           fail( "Error opening client socket" );
       }
       catch (NoSuchElementException e) {
           e.printStackTrace();
           fail( "The server didn't return a value" );
       }
   }

   @Test(timeout=3000)
   public void testC_PlayingARandomGame() throws IOException {
       final int UPPER = 200;
       final int RANGE = 300;
       final int TRIES = 9;

       final Random random = new Random();
       try {
           // run client
           Socket socket = new Socket( "localhost", 5150 );
           Scanner scanner = new Scanner ( socket.getInputStream() );
           PrintWriter writer = new PrintWriter( socket.getOutputStream(), true );
          
           int low = random.nextInt( UPPER );
           int hi = low + RANGE;
           int number = low + random.nextInt( RANGE );

           writer.println( low + " " + hi );

           int tries = 0;
           boolean gameOver = false;

           while (!gameOver) {
               int guess = scanner.nextInt();
               if (guess == number) {
                   writer.println( "won" );
                   gameOver = true;
               }
               else {
                   if (++tries > TRIES) {
                       writer.println( "lose" );
                       gameOver = true;
                   }
                   else {
                       if (guess < number) {
                           writer.println( "low" );
                       }
                       else {
                           writer.println( "high" );
                       }
                   }
               }
           }
           socket .close();
           scanner.close();
       }
       catch (IOException e) {
           e.printStackTrace();
           fail( "Error opening client socket" );
       }
       catch (NoSuchElementException e) {
           e.printStackTrace();
           fail( "The server didn't return a value" );
       }
   }
  
   @Test(expected = IOException.class)
   public void testD_RunsLast_ServerShutsDown() throws IOException {
       try {
           // running client #1...shuts down server
           Socket socket = new Socket( "localhost", 5150 );
           PrintWriter writer = new PrintWriter( socket.getOutputStream(), true );
          
           writer.println( "SHUT DOWN" );

           socket.close();
       }
       catch (IOException e) {
           e.printStackTrace();
           fail( "Error opening client socket" );
       }
       waitTwoSecondsBetweenTests();

       // running client #2...should throw exception (server should have stopped)
       new Socket( "localhost", 5150 ).close();
       fail( "Socket should not connect after server was shut down" );
   }
}

In this exercise you will create a server program that guesses numbers using binary search. A game is played each time a client contacts the server. Clients choose will choose a lower boundary between 0 and 200. The upper boundary will be the lower boundary plus 300 Figure 2 shows the flow of messages issued by the client (in green) and your server (in blue). When contacted, the server receives a message with 2 random numbers, indicating the lower and upper boundaries of the list (for example, "37 337". The server then replies with a guess (for example, “187") and receives from the client either a "high", "low", "won" or "lost" message. The first two replies indicate that more tries are allowed; the last two indicate that the game is over: it has been either won (the number was guessed) or lost (which should never happen using binary search) The connection between client and server ends when the game is over low..high] number high lowwin | lose Follow the steps below to implement your server program Figure 2. Guessing game message protocol Exercise 1 1. Create a Lab07 project. Create a class GuessingServer implementing your server program. The class should implement a main method where the server creates a socket connection at port 5150 to await for clients. The server should play the guessing game with any numbers of sequential clients. The server runs continuously until a client connects and sends "SHUT DOWN" as its initial message 2. 3. Download the JUnit test file GuessingServerTest.java from the class website and import it into the project. Test your server using its test cases

Explanation / Answer

1) For a stateless protocol (ie UDP), there is no problem because "connections" don't exist - multiple people can send packets to the same port, and their packets will arrive in whatever sequence. Nobody is ever in the "connected" state.

2) For a stateful protocol (like TCP), a connection is identified by a 4-tuple consisting of source and destination ports and source and destination IP addresses. So, if two different machines connect to the same port on a third machine, there are two distinct connections because the source IPs differ. If the same machine (or two behind NAT or otherwise sharing the same IP address) connects twice to a single remote end, the connections are differentiated by source port (which is generally a random high-numbered port).

3) Simply, if I connect to the same web server twice from my client, the two connections will have different source ports from my perspective and destination ports from the web server's. So there is no ambiguity, even though both connections have the same source and destination IP addresses.

4) Ports are a way to multiplex IP addresses so that different applications can listen on the same IP address/protocol pair. Unless an application defines its own higher-level protocol, there is no way to multiplex a port. If two connections using the same protocol have identical source and destination IPs and identical source and destination ports, they must be the same connection.

#include <stdio.h>

#include <string.h>   //strlen

#include <stdlib.h>

#include <errno.h>

#include <unistd.h>   //close

#include <arpa/inet.h>    //close

#include <sys/types.h>

#include <sys/socket.h>

#include <netinet/in.h>

#include <sys/time.h> //FD_SET, FD_ISSET, FD_ZERO macros

  

#define TRUE   1

#define FALSE 0

#define PORT 8888

int main(int argc , char *argv[])

{

    int opt = TRUE;

    int master_socket , addrlen , new_socket , client_socket[30] , max_clients = 30 , activity, i , valread , sd;

    int max_sd;

    struct sockaddr_in address;

      

    char buffer[1025]; //data buffer of 1K

      

    //set of socket descriptors

    fd_set readfds;

      

    //a message

    char *message = "ECHO Daemon v1.0 ";

  

    //initialise all client_socket[] to 0 so not checked

    for (i = 0; i < max_clients; i++)

    {

        client_socket[i] = 0;

    }

      

    //create a master socket

    if( (master_socket = socket(AF_INET , SOCK_STREAM , 0)) == 0)

    {

        perror("socket failed");

        exit(EXIT_FAILURE);

    }

  

    //set master socket to allow multiple connections , this is just a good habit, it will work without this

    if( setsockopt(master_socket, SOL_SOCKET, SO_REUSEADDR, (char *)&opt, sizeof(opt)) < 0 )

    {

        perror("setsockopt");

        exit(EXIT_FAILURE);

    }

  

    //type of socket created

    address.sin_family = AF_INET;

    address.sin_addr.s_addr = INADDR_ANY;

    address.sin_port = htons( PORT );

      

    //bind the socket to localhost port 8888

    if (bind(master_socket, (struct sockaddr *)&address, sizeof(address))<0)

    {

        perror("bind failed");

        exit(EXIT_FAILURE);

    }

    printf("Listener on port %d ", PORT);

     

    //try to specify maximum of 3 pending connections for the master socket

    if (listen(master_socket, 3) < 0)

    {

        perror("listen");

        exit(EXIT_FAILURE);

    }

      

    //accept the incoming connection

    addrlen = sizeof(address);

    puts("Waiting for connections ...");

     

    while(TRUE)

    {

        //clear the socket set

        FD_ZERO(&readfds);

  

        //add master socket to set

        FD_SET(master_socket, &readfds);

        max_sd = master_socket;

         

        //add child sockets to set

        for ( i = 0 ; i < max_clients ; i++)

        {

            //socket descriptor

            sd = client_socket[i];

             

            //if valid socket descriptor then add to read list

            if(sd > 0)

                FD_SET( sd , &readfds);

             

            //highest file descriptor number, need it for the select function

            if(sd > max_sd)

                max_sd = sd;

        }

  

        //wait for an activity on one of the sockets , timeout is NULL , so wait indefinitely

        activity = select( max_sd + 1 , &readfds , NULL , NULL , NULL);

    

        if ((activity < 0) && (errno!=EINTR))

        {

            printf("select error");

        }

          

        //If something happened on the master socket , then its an incoming connection

        if (FD_ISSET(master_socket, &readfds))

        {

            if ((new_socket = accept(master_socket, (struct sockaddr *)&address, (socklen_t*)&addrlen))<0)

            {

                perror("accept");

                exit(EXIT_FAILURE);

            }

          

            //inform user of socket number - used in send and receive commands

            printf("New connection , socket fd is %d , ip is : %s , port : %d " , new_socket , inet_ntoa(address.sin_addr) , ntohs(address.sin_port));

        

            //send new connection greeting message

            if( send(new_socket, message, strlen(message), 0) != strlen(message) )

            {

                perror("send");

            }

              

            puts("Welcome message sent successfully");

              

            //add new socket to array of sockets

            for (i = 0; i < max_clients; i++)

            {

                //if position is empty

                if( client_socket[i] == 0 )

                {

                    client_socket[i] = new_socket;

                    printf("Adding to list of sockets as %d " , i);

                     

                    break;

                }

            }

        }

          

        //else its some IO operation on some other socket :)

        for (i = 0; i < max_clients; i++)

        {

            sd = client_socket[i];

              

            if (FD_ISSET( sd , &readfds))

            {

                //Check if it was for closing , and also read the incoming message

                if ((valread = read( sd , buffer, 1024)) == 0)

                {

                    //Somebody disconnected , get his details and print

                    getpeername(sd , (struct sockaddr*)&address , (socklen_t*)&addrlen);

                    printf("Host disconnected , ip %s , port %d " , inet_ntoa(address.sin_addr) , ntohs(address.sin_port));

//Close the socket and mark as 0 in list for reuse

                    close( sd );

                    client_socket[i] = 0;

                }

                  

                //Echo back the message that came in

                else

                {

                    //set the string terminating NULL byte on the end of the data read

                    buffer[valread] = '';

                    send(sd , buffer , strlen(buffer) , 0 );

                }

            }

        }

    }

      

    return 0;

}

OutPut :

Hire Me For All Your Tutoring Needs
Integrity-first tutoring: clear explanations, guidance, and feedback.
Drop an Email at
drjack9650@gmail.com
Chat Now And Get Quote