简体   繁体   English

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

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

I've recently been playing around with Sockets in Java but I came across a problem. 我最近一直在用Java玩Sockets,但是遇到了一个问题。 The server get's stuck in the Server readLine(); 服务器卡在服务器readLine()中; I have no clue what is going on, if anyone can help that would be great. 我不知道这是怎么回事,如果有人可以帮助的话,那将是很好的。 I know that the problem is not that readLine() only returns when there is a new line character, but I am using println() not just print(). 我知道问题不在于readLine()仅在有换行符时才返回,而是我在使用println()而不只是print()。

Here is my current code: 这是我当前的代码:

Server Class: 服务器类别:

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;
    }
}

My Client Class: 我的客户类别:

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;
    }
}

My packet sender class: 我的封包寄件者类别:

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);
    }
}

Here's what's happening 这是发生了什么

From your client: 来自您的客户:

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

When this line runs, the server will be woken up from the accept line. 当此行运行时,服务器将从accept行中唤醒。 And block again at readLine() 然后在readLine()处再次阻止

Meanwhile, your client, goes through your PacketSender. 同时,您的客户端将通过您的PacketSender。 What does your PacketSender do? 您的PacketSender会做什么?

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

This opens a new connection! 这将打开一个新的连接! So your Client is waiting for the server to accept a connection. 因此,您的客户端正在等待服务器接受连接。 And the server is waiting for the client to send a message! 服务器正在等待客户端发送消息! You arrive at a deadlock. 您陷入僵局。

Here's how to fix it 这是解决方法

remove the following line. 删除以下行。

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

then pass the host address and port manually into your PacketSender. 然后将主机地址和端口手动传递到您的PacketSender中。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM