如何在java中的客户端和服务器之间进行通信

时间:2011-06-06 04:57:54

标签: java network-programming

我有一个聊天程序。现在代码适用于通过命令行在客户端和服务器之间进行通信。但它在运行时给出了异常(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);
    }
}
}

4 个答案:

答案 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完成通信,因为这很可能通过防火墙和代理。如果您计划任何严肃的事情,您可能想要阅读长轮询。