我如何使用从服务器到客户端的列表

时间:2019-06-04 14:38:01

标签: java serversocket

我正在为飞机的问题(用于学校)创建服务器和客户端。

问题是我如何使用带有Java套接字的列表,以便客户端能够选择飞机上的某个特定座位(如果有)。

通过使用案例,客户可以查看哪些座位可用,但是我不确定是否有更好的方法来解决这个问题

// It contains two classes : Server and ClientHandler 
// Save file as Server.java 

import java.io.*; 
import java.text.*; 
import java.util.*; 
import java.net.*; 

// Server class 
public class Server 
{ 
    public static void main(String[] args) throws IOException 
    { 
        // server is listening on port 5056 
        ServerSocket ss = new ServerSocket(5056); 

        // running infinite loop for getting 
        // client request 
        while (true) 
        { 
            Socket s = null; 

            try
            { 
                // socket object to receive incoming client requests 
                s = ss.accept(); 

                System.out.println("A new client is connected : " + s); 

                // obtaining input and out streams 
                DataInputStream dis = new DataInputStream(s.getInputStream()); 
                DataOutputStream dos = new DataOutputStream(s.getOutputStream()); 

                System.out.println("Assigning new thread for this client"); 

                // create a new thread object 
                Thread t = new ClientHandler(s, dis, dos); 

                // Invoking the start() method 
                t.start(); 

            } 
            catch (Exception e){ 
                s.close(); 
                e.printStackTrace(); 
            } 
        } 
    } 
} 

// ClientHandler class 
class ClientHandler extends Thread 
{ 
    DateFormat fordate = new SimpleDateFormat("yyyy/MM/dd"); 
    DateFormat fortime = new SimpleDateFormat("hh:mm:ss"); 
    final DataInputStream dis; 
    final DataOutputStream dos; 
    final Socket s; 


    // Constructor 
    public ClientHandler(Socket s, DataInputStream dis, DataOutputStream dos) 
    { 
        this.s = s; 
        this.dis = dis; 
        this.dos = dos; 
    } 

    @Override
    public void run() 
    { 
        String received; 
        String toreturn; 
        while (true) 
        { 
            try { 

                // Ask user what he wants 
                dos.writeUTF("What do you want?[Date | Time]..\n"+ 
                            "Type Exit to terminate connection."); 

                // receive the answer from client 
                received = dis.readUTF(); 

                if(received.equals("Exit")) 
                { 
                    System.out.println("Client " + this.s + " sends exit..."); 
                    System.out.println("Closing this connection."); 
                    this.s.close(); 
                    System.out.println("Connection closed"); 
                    break; 
                } 

                // creating Date object 
                Date date = new Date(); 

                // write on output stream based on the 
                // answer from the client 
                switch (received) { 

                    case "Date" : 
                        toreturn = fordate.format(date); 
                        dos.writeUTF(toreturn); 
                        break; 

                    case "Time" : 
                        toreturn = fortime.format(date); 
                        dos.writeUTF(toreturn); 
                        break; 
                    case "Seat" :
                        toreturn=

                    default: 
                        dos.writeUTF("Invalid input"); 
                        break; 
                } 
            } catch (IOException e) { 
                e.printStackTrace(); 
            } 
        } 

        try
        { 
            // closing resources 
            this.dis.close(); 
            this.dos.close(); 

        }catch(IOException e){ 
            e.printStackTrace(); 
        } 
    } 
} 

1 个答案:

答案 0 :(得分:0)

如果要将列表从服务器发送到客户端,可以使用Java对象序列化,如下所示:

您可以使用这样的类来存储仍然可用的座位。重要的部分是该类必须实现接口Serializable

package serializeList;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;

public class Seats implements Serializable {

    //recommended for serializable classes (but not needed)
    private static final long serialVersionUID = -2916554242169592691L;

    private List<String> availableSeats;

    public Seats(List<String> availableSeats) {
        this.availableSeats = availableSeats;
    }

    public static Seats findAvailableSeats() {
        List<String> seats = new ArrayList<String>();
        //TODO find the avialable seats somehow...
        return new Seats(seats);
    }

    public List<String> getAvailableSeats() {
        return availableSeats;
    }
    public void setAvailableSeats(List<String> availableSeats) {
        this.availableSeats = availableSeats;
    }
}

然后,您可以像这样更改服务器代码:

import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.ObjectOutputStream;
import java.net.Socket;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Date;

// ClientHandler class 
class ClientHandler extends Thread {

    DateFormat fordate = new SimpleDateFormat("yyyy/MM/dd");
    DateFormat fortime = new SimpleDateFormat("hh:mm:ss");
    final DataInputStream dis;
    final DataOutputStream dos;
    final Socket s;
    ObjectOutputStream oos;

    // Constructor 
    public ClientHandler(Socket s, DataInputStream dis, DataOutputStream dos) {
        this.s = s;
        this.dis = dis;
        this.dos = dos;
        try {
            this.oos = new ObjectOutputStream(dos);
        }
        catch (IOException e) {
            e.printStackTrace();
        }
    }

    @Override
    public void run() {
        String received;
        String toreturn;
        while (true) {
            try {

                // Ask user what he wants 
                dos.writeUTF("What do you want?[Date | Time]..\n" + "Type Exit to terminate connection.");

                // receive the answer from client 
                received = dis.readUTF();

                if (received.equals("Exit")) {
                    System.out.println("Client " + this.s + " sends exit...");
                    System.out.println("Closing this connection.");
                    this.s.close();
                    System.out.println("Connection closed");
                    break;
                }

                // creating Date object 
                Date date = new Date();

                // write on output stream based on the 
                // answer from the client 
                switch (received) {

                    case "Date":
                        toreturn = fordate.format(date);
                        dos.writeUTF(toreturn);
                        break;

                    case "Time":
                        toreturn = fortime.format(date);
                        dos.writeUTF(toreturn);
                        break;
                    case "Seat":
                        Seats seatsToReturn = Seats.findAvailableSeats();
                        oos.writeObject(seatsToReturn);
                    default:
                        dos.writeUTF("Invalid input");
                        break;
                }
            }
            catch (IOException e) {
                e.printStackTrace();
            }
        }

        try {
            // closing resources 
            this.dis.close();
            this.dos.close();

        }
        catch (IOException e) {
            e.printStackTrace();
        }
    }
}

当然,您必须在客户端添加一些更改。也许像这样:

import java.io.DataOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;

public class SeatClient {

    private DataOutputStream dos; 
    private ObjectInputStream ois;

    public SeatClient() {
        //TODO create the object input stream (from your socket streams)
        //TODO also create the data output stream to send to the server
    }

    public void getSeats() {
        String toSend = "Seat";
        try {
            dos.writeUTF(toSend);//to let the server know you want to know the available seats
            Seats seats = (Seats) ois.readObject();//assuming that the next received object is from type Seats
            //TODO do something useful with the seats...
        }
        catch (IOException e) {
            e.printStackTrace();
        }
        catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
    }
}

因此,现在您可以将可用席位列为客户列表。如果您不希望列表包含字符串,那么只要通用类型(替换字符串的类型)还实现了Serializable(许多诸如List,String和许多als这样的类),它也是可能的。