Java套接字:服务器如何从客户端读取多行

时间:2015-03-05 10:27:00

标签: java sockets asynchronous

我使用Java编程语言一对一地创建聊天应用程序 我遇到了问题:客户端在收到服务器发来的消息之前无法发送新消息。

2 个答案:

答案 0 :(得分:1)

您应该有一个多线程应用程序。 客户端将运行2个线程: 1)将在发送按钮上运行的发送者线程。您可以在每次单击“发送”按钮时创建此线程的新实例。 2)接收器线程将继续运行并检查流以查找任何消息。一旦它在流上获得消息,它将在控制台上写入相同的内容。

很快会使用代码更新您。 感谢

使用其他端口

编写服务器时,可以长时间编写此代码
package com.clients;

import java.awt.BorderLayout;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.awt.event.WindowListener;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;

import java.net.Socket;
import java.net.UnknownHostException;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.JTextField;

public class ClientFullDuplex extends JFrame implements ActionListener {

    private JFrame jframe;
    private JPanel jp1, jp2;
    private JScrollPane jsp;
    private JTextArea jta;
    private JTextField jtf;
    private JButton send;
    private Thread senderthread;
    private Thread recieverthread;
    private Socket ds;
    private boolean sendflag;

    public static void main(String[] args) {
        try {
            ClientFullDuplex sfd = new ClientFullDuplex();
        } catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }

    }

    public ClientFullDuplex() throws UnknownHostException, IOException {
        initGUI();
        ds = new Socket("127.0.0.1", 1124);
        initNetworking();
    }

    public void initGUI() {

        jframe = new JFrame();
        jframe.setTitle("Client");
        jframe.setSize(400, 400);
        jp1 = new JPanel();
        jta = new JTextArea();
        jsp = new JScrollPane(jta);

        jtf = new JTextField();
        send = new JButton("Send");
        send.addActionListener(this);

        jp1.setLayout(new GridLayout(1, 2, 10, 10));
        jp1.add(jtf);
        jp1.add(send);

        jframe.add(jp1, BorderLayout.SOUTH);
        jframe.add(jsp, BorderLayout.CENTER);
        jframe.setVisible(true);
        jframe.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        jta.append("hello client");

    }

    @Override
    public synchronized void addWindowListener(WindowListener arg0) {
        // TODO Auto-generated method stub
        super.addWindowListener(arg0);
        new WindowAdapter() {
            @Override
            public void windowClosing(WindowEvent arg0) {
                // TODO Auto-generated method stub
                if (ds != null)
                    try {

                        ds.close();
                        System.exit(0);
                    } catch (IOException e) {
                        // TODO Auto-generated catch block
                        e.printStackTrace();
                    }
            }
        };

    }

    public void initNetworking() {
        try {
            recieverthread = new Thread(r1);
            recieverthread.start();

        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    Runnable r1 = new Runnable() {

        @Override
        public void run() {
            try {
                System.out.println(Thread.currentThread().getName()
                        + "Reciver Thread Started");
                recieveMessage(ds);
            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }

        }
    };

    Runnable r2 = new Runnable() {

        @Override
        public void run() {
            try {
                System.out.println(Thread.currentThread().getName()
                        + "Sender Thread Started");
                sendMessage(ds);
            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }

        }
    };

    public void recieveMessage(Socket rms) throws IOException {
        while (true) {
            System.out.println(Thread.currentThread().getName()
                    + "Reciver Functionality");
            BufferedReader br = new BufferedReader(new InputStreamReader(
                    rms.getInputStream()));
            String line = br.readLine();
            System.out.println(line);
            jta.append("\nServer:"+line);
        }
    }

    public void sendMessage(Socket sms) throws IOException {

        System.out.println(Thread.currentThread().getName()
                + "Sender Functionality");
        PrintWriter pw = new PrintWriter(sms.getOutputStream(), true);
        String sline = jtf.getText();
        System.out.println(sline);
        pw.println(sline);
        jtf.setText("");

    }

    @Override
    public void actionPerformed(ActionEvent e) {
        // TODO Auto-generated method stub
        if (e.getSource() == send) {
            senderthread = new Thread(r2);
            senderthread.start();
        }
    }

}

答案 1 :(得分:0)

这是我从之前的帖子中复制和编辑的代码。 问题是来自套接字的输入流是阻塞的。所以我的建议是阅读java中的异步套接字并重构下面的代码。 除此之外,编辑帖子并不困难。

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.ArrayList;
import java.util.logging.Level;
import java.util.logging.Logger;

public class Server {

    public static void main(String[] args) {

        Server chatServer = new Server(5555);
        System.out.println("###Start listening...###");
        chatServer.startListening();
        chatServer.acceptClientRequest();
    }

    private ServerSocket listeningSocket;
    private Socket serviceSocket;
    private int TCPListeningPort;
    private ArrayList<SocketHanding> connectedSocket;

    public Server(int TCPListeningPort) 
    {
        this.TCPListeningPort = TCPListeningPort;
        connectedSocket = new ArrayList<SocketHanding>();
    }

    public void startListening()
    {           
        try 
        {
            listeningSocket = new ServerSocket(TCPListeningPort);               
        } 
        catch (IOException ex) {
            Logger.getLogger(Server.class.getName()).log(Level.SEVERE, null, ex);
        }       
    }

    public void acceptClientRequest()
    {
        try 
        {
            while (true)
            {
                serviceSocket = listeningSocket.accept();

                SocketHanding _socketHandling = new SocketHanding(serviceSocket);
                connectedSocket.add(_socketHandling);

                Thread t = new Thread(_socketHandling);
                t.start();



                System.out.println("###Client connected...### " + serviceSocket.getInetAddress().toString() );
            }
        } 
        catch (IOException ex) {
            Logger.getLogger(Server.class.getName()).log(Level.SEVERE, null, ex);
        }
    }
}

class SocketHanding implements Runnable
{
    private Socket _connectedSocket;
    private PrintWriter socketOut;
    private InputStream socketIn;
    private boolean threadRunning = true;

    private String rmsg;

    public SocketHanding(Socket connectedSocket) throws IOException
    {
        _connectedSocket = connectedSocket;

        socketOut = new PrintWriter(_connectedSocket.getOutputStream(), true);
        socketIn = _connectedSocket.getInputStream();
    }

    private void closeConnection() throws IOException 
    {
        threadRunning = false;
        socketIn.close();
        socketOut.close();
        _connectedSocket.close();
    }

    public void sendMessage(String message)
    {
        socketOut.println(message);
    }

    private String receiveMessage() throws IOException 
    {   
        String t = "";

        if (_connectedSocket.getInputStream().available() > 0)
        {           
            byte[] b = new byte[8192];
            StringBuilder builder = new StringBuilder();
            int bytesRead = 0;

            if ( (bytesRead = _connectedSocket.getInputStream().read(b)) > -1 )
            {
                builder.append(new String(b, 0, b.length).trim());
            }

            t = builder.toString();
        }

        return t; 
    }

    @Override
    public void run()
    {
        while (threadRunning)
        {               
            try 
            {
                rmsg = receiveMessage();
                System.out.println(rmsg);

                if(rmsg.equalsIgnoreCase("bye"))
                {   
                    System.out.println("###...Done###");

                    closeConnection();                                              
                    break;
                }
                else
                {   
                    String smsg = "";

                    BufferedReader keyboard = new BufferedReader(new InputStreamReader(System.in));

                    smsg = keyboard.readLine();                     
                    keyboard.close();

                    sendMessage("Server: "+smsg);
                }
            } 
            catch (IOException e) 
            {
                e.printStackTrace();
            }
        }
    }
}