Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/sockets/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Sockets-服务器卡在.readLine()中-Java_Java_Sockets_Readline - Fatal编程技术网

Sockets-服务器卡在.readLine()中-Java

Sockets-服务器卡在.readLine()中-Java,java,sockets,readline,Java,Sockets,Readline,我最近一直在玩Java中的套接字,但我遇到了一个问题。服务器get卡在服务器readLine()中;我不知道发生了什么事,如果有人能帮忙,那就太好了。我知道问题不在于readLine()只在有新行字符时返回,而是我使用的是println()而不仅仅是print() 这是我目前的代码: 服务器类: package packets.sidedcomputer; import java.io.BufferedReader; import java.io.IOException; import jav

我最近一直在玩Java中的套接字,但我遇到了一个问题。服务器get卡在服务器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.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()处再次阻塞

同时,你的客户,通过你的包裹寄件人。你的包裹寄件人是做什么的

Socket socket = new Socket(hostName, Integer.parseInt(port));
这将打开一个新连接!因此,您的客户端正在等待服务器接受连接。服务器正在等待客户端发送消息!你陷入了僵局

下面是如何修复它 拆下以下行

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

然后手动将主机地址和端口传递到PacketSender中。

默认情况下,套接字是阻塞的。这意味着,如果没有可读取的输入,读取函数将阻塞并不会返回,直到有内容可读取。可能是@JoachimPileborg的重复,这是我的问题,应该有内容可供读取。。。我知道readLine()只在有新行字符的情况下返回,但我使用的是println not print,所以新行字符应该在那里…您没有陷入死锁状态,客户端和服务器都在等待输入?向服务器和客户端添加一些日志记录可能是一个好主意,这样您就可以看到它们在做什么。@JoachimPileborg它确实可以发送数据,而服务器已经在等待数据通过。感谢您的帮助,唯一的问题是我正在从另一个位置使用clientSocket。。。因此,我将sendData更改为使用套接字作为参数,并得到以下错误:。。。这里还有ClientReciever@gegy1000,你必须从更大的角度来理解这一点。从这里,希望您能更好地理解连接的工作方式。对于初学者,通常不应在接受连接的同一线程中读取。@gegy1000请记住,创建套接字并不是无害的。这一小行“newsocket(host,port)”导致整个TCP握手发生。
this.clientSocket = new Socket("192.168.1.25", 10501);