我最近一直在使用Java中的套接字,但我遇到了一个问题。服务器卡在服务器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);
}
}
答案 0 :(得分:0)
来自您的客户:
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。