Java ServerSocket / Socket Chat Program

时间:2014-10-26 16:12:38

标签: java sockets chat server

我试着做一个小聊天程序,但它确实不想工作。我的服务器和客户端大致相同:它们创建一个新的套接字和一个新的聊天(GUI)。有人能帮我找到我犯的错误吗?

服务器代码:

import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.IOException;

import java.net.Socket;
import java.net.ServerSocket;

public class Server {
    private     Chat            ch      = null;
    private     ServerSocket    server  = null;
    private     Socket          s       = null;
    private     BufferedReader  in      = null;
    private     BufferedWriter  out     = null;

    public Server() {
        try {
            server = new ServerSocket(1792);
            s = server.accept();
            in = new BufferedReader(new InputStreamReader(s.getInputStream()));
            out = new BufferedWriter(new OutputStreamWriter(s.getOutputStream()));
            ch = new Chat("Server", out);
        } catch (IOException ioe) {

        }

        new Thread(new Runnable() {
            public void run() {
                while (true) {
                    try {
                        String line = in.readLine();
                        ch.showString(line);
                    } catch (IOException e) {
                        System.exit(0);     // exit program when connection is lost
                        return;
                    }
                }
            }
        }).start();
    }
}

客户代码:

import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.IOException;

import java.net.Socket;

public class Client {
    private     Chat            ch      = null;
    private     Socket          s       = null;
    private     BufferedReader  in      = null;
    private     BufferedWriter  out     = null;

    public Client() {
        try {
            s = new Socket("localHost", 1792);
            in = new BufferedReader(new InputStreamReader(s.getInputStream()));
            out = new BufferedWriter(new OutputStreamWriter(s.getOutputStream()));
            ch = new Chat("Client", out);
        } catch (IOException ioe) {

       }

        new Thread(new Runnable() {
            public void run() {
                while (true) {
                    try {
                        String line = in.readLine();
                        ch.showString(line);
                    } catch (IOException e) {
                        System.exit(0);     // exit program when connection is lost
                        return;
                    }
                }
            }
        }).start();
    }
}

聊天(GUI)代码:

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Insets;

import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.JFrame;
import javax.swing.JTextField;
import javax.swing.JButton;
import javax.swing.JPanel;
import javax.swing.JLabel;

import java.io.BufferedWriter;
import java.io.IOException;

public class Chat implements ActionListener {
    protected   JFrame          fr;
    private     JPanel          p;
    private     JTextField      tf;
    private     JButton         b;
    private     int             lines   = 20;
    private     JLabel[]        l       = new JLabel[lines];
    private     String          title   = "";
    private     BufferedWriter  out;

    public Chat(String name, BufferedWriter bw) {
        title = name;
        out = bw;

        fr = new JFrame(title);
        fr.setLayout(new BorderLayout());
        fr.setDefaultCloseOperation(fr.EXIT_ON_CLOSE);
        fr.setSize(400, 475);
        fr.setLocationRelativeTo(null);
        fr.setResizable(false);
        fr.setVisible(true);

        Insets in = fr.getInsets();
        int width = fr.getWidth() - in.left - in.right;
        int height = fr.getHeight() - in.top - in.bottom;

        p = new JPanel();
        p.setLayout(null);
        p.setBackground(Color.WHITE);
        fr.add(p, BorderLayout.CENTER);

        tf = new JTextField();
        tf.setHorizontalAlignment(tf.LEFT);
        tf.addActionListener(this);
        tf.setBounds(0, 400, 300, height-400);
        p.add(tf);

        b = new JButton("Send");
        b.setBounds(300, 400, width-300, height-400);
        b.addActionListener(this);
        p.add(b);

        p.validate();
        fr.validate();

        p.repaint();
        fr.repaint();

        for(int i=0;i<lines;i++) {
            l[i] = new JLabel("");
            l[i].setHorizontalAlignment(l[i].LEFT);
            l[i].setBounds(0, 400*i/lines, 500, 400/lines);
            p.add(l[i]);
        }
    }

    public void showString(String text) {
        if (text.equals("")) return;
        for(int i=0;i<lines-1;i++) {
            l[i].setText(l[i+1].getText());
        }
        l[lines-1].setText(text);
    }

    public void actionPerformed(ActionEvent ae) {
        String text = tf.getText();
        try {
            showString(text);
            out.write(text);
            out.flush();
            tf.setText("");
        } catch (IOException ioe) {

        }
    }
}

1 个答案:

答案 0 :(得分:1)

readLine()函数等待行尾。 在您的聊天课中,在写入输出流时,您永远不会给它一个结尾。因此,服务器和客户端都会在in.readLine()中等待行尾字符,以便完成读取单行。 在写入输出流的每一行之后,需要为其指定行尾字符。只有冲洗它是不够的。

只需在聊天类中修改此部分即可。

旧代码

        out.write(text);
        out.flush();

新代码

        out.write(text);
        out.write('\n');
        out.flush();

休息所有代码都工作得很好。祝你好运!