今天重新写一下聊天室的时候发现,创建两个窗口,第一个窗口第一次输出后就会堵塞,纠结中··以下是代码:
服务端:
package Inernet;import java.awt.BorderLayout;
import java.io.IOException;
import java.io.PrintWriter;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.ArrayList;
import java.util.Scanner;import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.border.EmptyBorder;public class fffffff extends JFrame { private JPanel contentpanel;
private JTextArea message;
private ServerSocket server;
private ArrayList<Socket> client=new  ArrayList<Socket>();
private Scanner in;
private PrintWriter out;
private Socket s;
/*
 * launch the main
 */
public static void main(String[] agrs)
{
fffffff frame=new fffffff();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setVisible(true);
frame.createThread();
}

private void createThread()
{
s=new Socket();
try {
server=new ServerSocket(6000);
} catch (IOException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
while(true)
{
try {
message.append("等待连接...\n");
s=server.accept();
message.append("连接成功...."+s+"\n");
client.add(s);
new Thread(new Runnable() { @Override
public void run() {
// TODO Auto-generated method stub
try {

in=new Scanner(s.getInputStream());
while(s.isConnected())
{

String str=in.nextLine();
// System.out.println(str);
message.append(str);
for(Socket i:client)
{

out=new PrintWriter(i.getOutputStream(),true);
out.println(str);
out.flush();
}
}
} catch (IOException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
}
}).start();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
/*
 * create the frame
 */
public fffffff()
{
contentpanel=new JPanel();
setContentPane(contentpanel);
contentpanel.setBorder(new EmptyBorder(5,5,5,5));
setBounds(300, 300, 300, 300);
contentpanel.setLayout(new BorderLayout());
setTitle("服务端");
JScrollPane jscrollpanel=new JScrollPane();
contentpanel.add(jscrollpanel,BorderLayout.CENTER);
message=new JTextArea();
jscrollpanel.setViewportView(message);

}
}客户端:package Inernet;import java.awt.BorderLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.IOException;
import java.io.PrintWriter;
import java.net.InetAddress;
import java.net.Socket;
import java.net.UnknownHostException;
import java.util.Scanner;import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.JTextField;
import javax.swing.border.EmptyBorder;public class ffff extends JFrame{ private JPanel contentpanel;
private JTextField name;
private JTextArea message;
private JTextField send_message;
private JButton send;
private Socket client;
private Scanner in;
private PrintWriter out;
/*
 * launch the main
 */
public static void main(String[] agrs)
{
ffff frame=new ffff();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setVisible(true);
frame.createClient();
}
private void createClient()
{
try {
client=new Socket("127.0.0.1",6000);
new Thread(new Runnable() {

@Override
public void run() {
// TODO Auto-generated method stub
while(client.isConnected())
{
try {
in=new Scanner(client.getInputStream());
String str=in.nextLine()+"\n\r";
message.append(str);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}).start();
} catch (UnknownHostException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}

}
/*
 * create the frame
 */
public ffff()
{
setTitle("客户端");
contentpanel=new JPanel();
setContentPane(contentpanel);
contentpanel.setBorder(new EmptyBorder(5,5,5,5));
setBounds(300, 300, 350, 400);
contentpanel.setLayout(new BorderLayout());

JPanel toppanel=new JPanel();
contentpanel.add(toppanel,BorderLayout.NORTH);
toppanel.add(new JLabel("昵称"));
name=new JTextField(20);
toppanel.add(name);
JScrollPane jscrollpanl=new JScrollPane();
contentpanel.add(jscrollpanl,BorderLayout.CENTER);
message=new JTextArea();
jscrollpanl.setViewportView(message);
JPanel bottompanel =new JPanel();
contentpanel.add(bottompanel,BorderLayout.SOUTH);
bottompanel.add(new JLabel("发送:"));
send_message=new JTextField(15);
bottompanel.add(send_message);
send=new JButton("发送");
bottompanel.add(send);
send.addActionListener(new ActionListener() {

@Override
public void actionPerformed(ActionEvent arg0) {
// TODO Auto-generated method stub
try {
out=new PrintWriter(client.getOutputStream());
String str=name.getText()+":"+send_message.getText();
out.println(str);
// System.out.println(str);
out.flush();
send_message.setText("");
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}

}
});

}
}

解决方案 »

  1.   

    嗯,你开两个窗口,然后在第一个窗口发送数据,发送一次后就会出现堵塞,我试了一下是在i服务端的n.nextline(),这边堵塞,接下来无论输什么数据都无法发送了,我想不明白,前面我写过一个没问题的对比了一下还是没看出来= =
      

  2.   

    原因确实是在Server端用java.util.Scanner的nextLine方法造成的。
    我试了一些,读行的时候换成java.io.BufferedReader就OK了。
    关于java.util.Scanner这个类,我几乎没用过,所以有待研究,这里就不说了。
      

  3.   

    我觉得,虽然服务器端为每个客户端请求新建了线程,但都使用一个变量in!!! 所以每次有新的客户端连接的时候,服务端为先期连接的客户端线程而使用的变量 in 都被新的线程重新定义了。
    解决的办法是为每个线程创建一个 Scanner对象 in.服务端代码修改一下,楼主试试:@Override
    public void run() {
    // TODO Auto-generated method stub
    try {//in=new Scanner(s.getInputStream());
    Scanner in=new Scanner(s.getInputStream());   //改成这样。本线程独有。
    while(s.isConnected())
    {String str=in.nextLine();
    //  System.out.println(str);
    //message.append(str);
    message.append(str+"\r\n");    //加换行
    for(Socket i:client)
    {out=new PrintWriter(i.getOutputStream(),true);
    out.println(str);
    out.flush();
    }
    }
    }
      

  4.   

    楼上正解,看来我是错的,我测试的时候用的BufferedReader是在run方法内部定义的。学艺不精啊!