我有一个聊天程序。现在代码适用于通过命令行在客户端和服务器之间进行通信。但它在运行时给出了异常(java.net.SocketException:Socket已关闭)。请帮我解决这个问题。
在java聊天程序中,如何在客户端和服务器之间实现通信?
即
客户端< - >服务器(服务器和客户端之间)
or
客户端A< - >服务器< - >客户端B(服务器充当两个客户端之间的桥梁)
双向通信是否可以通过单个插槽实现? 还有其他方法吗? 如何同时与多个客户沟通?
class Server
{
ServerSocket server;
Socket client;
public Server()
{
try
{
server = new ServerSocket(2000);
System.out.println("\tServer Started..........");
while (true)
{
client = server.accept();
Send objsend = new Send(client);
Recive objrecive = new Recive(client);
//client.close();
}
}
catch (Exception e)
{
System.out.println("Exception4 " + e);
}
}
public static void main(String arg[])
{
new Server();
}
}
class Recive implements Runnable
{
Socket client;
public Recive(Socket client1)
{
client=client1;
Thread trsend=new Thread(this);
trsend.start();
}
public void run()
{
ObjectInputStream ois;
Message M=new Message();
try
{
ois = new ObjectInputStream(client.getInputStream());
M = (Message)ois.readObject();
M.display();
ois.close();
}
catch (Exception e)
{
System.out.println("Exception1 " + e);
}
}
}
class Send implements Runnable
{
Socket client;
public Send(Socket client1)
{
client=client1;
Thread trrecive=new Thread(this);
trrecive.start();
}
public void run()
{
Message M=new Message();
InputStreamReader isr=new InputStreamReader(System.in);
BufferedReader br=new BufferedReader(isr);
try
{
System.out.println("Me(server)");
M.strmessage=br.readLine();
ObjectOutputStream oos=new ObjectOutputStream(cli ent.getOutputStream());
oos.writeObject((Message)M);
oos.flush();
oos.close();
}
catch (Exception e)
{
System.out.println("Exception " + e);
}
}
}
class Client
{
public static void main(String arg[])
{
try
{
Send objsend=new Send();
Recive objrecive=new Recive();
}
catch(Exception e)
{
System.out.println("Exception "+e);
}
}
}
class Send implements Runnable
{
public Send()
{
Thread trsend=new Thread(this);
trsend.start();
}
public void run()
{
try
{
Message M=new Message();
InputStreamReader isr=new InputStreamReader(System.in);
BufferedReader br=new BufferedReader(isr);
while(true)
{
System.out.println("Me(client)");
M.strmessage=br.readLine();
Socket client=new Socket("localhost",2000);
ObjectOutputStream oos=new ObjectOutputStream(client.getOutputStream());
oos.writeObject((Message)M);
oos.flush();
oos.close();
}
}
catch(Exception e)
{
System.out.println("Exception "+e);
}
}
}
class Recive implements Runnable
{
public Recive()
{
Thread trrecive=new Thread(this);
trrecive.start();
}
public void run()
{
try
{
while(true)
{
Socket client=new Socket("localhost",2000);
ObjectInputStream ois=new ObjectInputStream(client.getInputStream());
Message CNE=(Message)ois.readObject();
CNE.display();
ois.close();
}
}
catch(Exception e)
{
System.out.println("Exception "+e);
}
}
}
答案 0 :(得分:2)
首先,不要在每次运行中关闭流()。
其次,检查您使用的服务器端口是否空闲。
答案 1 :(得分:2)
此程序使您的电脑兼容主机和服务器。
import java.io.IOException;
import java.net.*;
public class ClientServer {
static byte[] buffer = new byte[100];
private static void runClient() throws IOException {
byte buffer[] = new byte[100];
InetAddress address = InetAddress.getLocalHost();
DatagramSocket ds=new DatagramSocket();
int pos = 0;
while (pos<buffer.length) {
int c = System.in.read();
buffer[pos++]=(byte)c;
if ((char)c =='\n')
break;
}
System.out.println("Sending " + pos + " bytes");
ds.send(new DatagramPacket(buffer, pos, address, 3000));
}
private static void runServer() throws IOException {
InetAddress address = InetAddress.getLocalHost();
DatagramSocket ds = new DatagramSocket(3000, address);
DatagramPacket dp = new DatagramPacket(buffer, buffer.length);
ds.receive(dp);
String s=new String(dp.getData(),0,dp.getLength());
System.out.print(s);
}
public static void main(String args[]) throws IOException {
if (args.length == 1) {
runClient();
} else {
runServer();
}
}
}
也请关注this link
答案 2 :(得分:1)
可能有多个地方可能抛出异常。如果没有堆栈跟踪,就很难准确地说明失败的原因。
但根本原因主要是由于您在读取消息后关闭Receiver线程中套接字的InputStream,并在发送消息后关闭发件人线程中套接字的OutputStream。关闭这些流中的任何一个都将自动关闭套接字,因此如果尝试对其执行任何进一步操作,将抛出SocketException。
如果您需要确保服务器和客户端不会以如此突然的方式关闭,则必须继续读取InputStream(例如,直到您收到要关闭的特殊消息)。与此同时,您还必须继续写入OutputStream。双向通信肯定是可能的,并且发布的代码能够相同(如果套接字保持打开状态)。
如果必须处理多个客户端,则服务器上需要多个读写器线程,每个线程都在监听从ServerSocket.accept()
返回的Socket实例;简单来说,您需要一个读写器对,监听服务器上每个客户端的不同套接字。目前,多个客户端可以连接到服务器,因为每个传入连接都在服务器上提供了自己的客户端Socket对象,该对象提供给各个读写器线程。主服务器线程可以继续接收传入连接并将实际工作委托给读写器对。
答案 3 :(得分:0)
因此,您将拥有一台服务器,每个客户端都会注册并与服务器通信,这会将消息转发给其他客户端。
通常通过HTTP完成通信,因为这很可能通过防火墙和代理。如果您计划任何严肃的事情,您可能想要阅读长轮询。