簡體   English   中英

套接字-服務器卡在in.readLine()中-Java

[英]Sockets - Server getting stuck on in.readLine() - Java

我最近一直在用Java玩Sockets,但是遇到了一個問題。 服務器卡在服務器readLine()中; 我不知道這是怎么回事,如果有人可以幫助的話,那將是很好的。 我知道問題不在於readLine()僅在有換行符時才返回,而是我在使用println()而不只是print()。

這是我當前的代碼:

服務器類別:

package packets.sidedcomputer;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.ArrayList;
import java.util.List;

import packets.Packet;
import packets.data.PacketData;
import packets.info.ClientInfo;
import packets.reciever.PacketReciever;
import packets.sender.PacketSender;
import packets.side.Side;

public class Server extends SidedComputer
{
    volatile boolean finished = false;

    public ServerSocket serverSocket;

    public volatile List<ClientInfo> clients = new ArrayList<ClientInfo>();

    public void stopServer()
    {
        finished = true;
    }

    public Server()
    {
        try 
        {
            serverSocket = new ServerSocket(10501);
        } 
        catch (IOException e)
        {
            e.printStackTrace();
        }
    }

    @Override
    public void run()
    {
        try 
        {
            while (!finished)
            {
                Socket clientSocket = serverSocket.accept();  

                if(clientSocket != null)
                {
                    ClientInfo clientInfo = new ClientInfo(clientSocket);

                    this.clients.add(clientInfo);

                    BufferedReader in = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));

                    String dataString = in.readLine();

                    while(dataString != null && !dataString.equals(""))
                    {
                        PacketReciever packetReciever = new PacketReciever();

                        PacketData packetData = new PacketData();

                        packetData.decodeInto(dataString);

                        Packet packet = packetReciever.recievePacket(packetData, packetData.packetID, getSide(), clientSocket.getLocalAddress().getHostAddress().toString(), clientSocket.getLocalPort() + "");

                        PacketSender packetSender = new PacketSender();

                        for (ClientInfo client : this.clients)
                        {
                            PrintWriter out = new PrintWriter(client.socket.getOutputStream(), true);
                            packetSender.sendPacketToClient(packet, out);
                        }

                        dataString = in.readLine();
                    }

                    serverSocket.close();
                }
            }
        } 
        catch (Exception e) 
        {
            e.printStackTrace();
            System.exit(1);
        }
    }

    @Override
    public Side getSide() 
    {
        return Side.SERVER;
    }
}

我的客戶類別:

package packets.sidedcomputer;

import java.io.IOException;
import java.net.Socket;
import java.net.UnknownHostException;
import java.util.Scanner;

import packets.MessagePacket;
import packets.sender.PacketSender;
import packets.side.Side;

public class Client extends SidedComputer
{
    volatile boolean finished = false;

    volatile String username;

    volatile Server server;

    public Socket clientSocket;

    public ClientReciever reciever;

    public Client(Server server, String username) throws UnknownHostException, IOException
    {
        this.username = username;
        this.server = server;
        this.reciever = new ClientReciever(this);
    }

    public void stopClient()
    {
        finished = true;
    }

    @Override
    public void run()
    {
        Scanner scanner = new Scanner(System.in);

        reciever.start();

        while(!finished)
        {
            try 
            {
                this.clientSocket = new Socket("192.168.1.25", 10501);

                String line;

                while((line = scanner.nextLine()) != null)
                {     
                    PacketSender sender = new PacketSender();

                    sender.sendPacket(new MessagePacket(line, username), clientSocket.getLocalAddress().getHostAddress().toString(), "" + clientSocket.getPort());
                }
            }
            catch (Exception e) 
            {
                e.printStackTrace();
            }

        }

        scanner.close();
    }

    @Override
    public Side getSide() 
    {
        return Side.CLIENT;
    }
}

我的封包寄件者類別:

package packets.sender;

import java.io.IOException;
import java.io.PrintWriter;
import java.net.Socket;
import java.net.UnknownHostException;

import packets.Packet;
import packets.data.PacketData;

public class PacketSender implements IPacketSender
{
    @Override
    public void sendPacket(Packet packet, String host, String port)
    {
        if(packet.getDefualtID() == 0)
        {
            PacketData packetData = new PacketData(packet.getDefualtID());

            packet.writeData(packetData);

            String data = packetData.encodeIntoString();

            sendData(host, port, data);
        }
    }

    protected void sendData(String hostName, String port, String data)
    {
        try 
        {

            try 
            (
                Socket socket = new Socket(hostName, Integer.parseInt(port));
                PrintWriter out = new PrintWriter(socket.getOutputStream(), true);
            ) 
            {
                out.println(data);
            } 
            catch (UnknownHostException e)
            {
                System.err.println("Don't know about host " + hostName);
                System.exit(1);
            } 
            catch (IOException e) 
            {
                System.err.println("Couldn't get I/O for the connection to " + hostName);
                System.exit(1);
            } 
        }
        catch (Exception e) 
        {
            e.printStackTrace();
        }
    }

    public void sendPacketToClient(Packet packet, PrintWriter out)
    {
        PacketData packetData = new PacketData(packet.getDefualtID());

        packet.writeData(packetData);

        String data = packetData.encodeIntoString();

        out.println(data);
    }
}

這是發生了什么

來自您的客戶:

this.clientSocket = new Socket("192.168.1.25", 10501);

當此行運行時,服務器將從accept行中喚醒。 然后在readLine()處再次阻止

同時,您的客戶端將通過您的PacketSender。 您的PacketSender會做什么?

Socket socket = new Socket(hostName, Integer.parseInt(port));

這將打開一個新的連接! 因此,您的客戶端正在等待服務器接受連接。 服務器正在等待客戶端發送消息! 您陷入僵局。

這是解決方法

刪除以下行。

this.clientSocket = new Socket("192.168.1.25", 10501);

然后將主機地址和端口手動傳遞到您的PacketSender中。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM