读书人

生手求解socket写聊天室的时候nex

发布时间: 2012-09-29 10:30:01 作者: rapoo

新手求解,socket写聊天室的时候,nextLine堵塞了
今天重新写一下聊天室的时候发现,创建两个窗口,第一个窗口第一次输出后就会堵塞,纠结中··

以下是代码:
服务端:
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();
}

}
});

}
}


[解决办法]
我觉得,虽然服务器端为每个客户端请求新建了线程,但都使用一个变量in!!! 所以每次有新的客户端连接的时候,服务端为先期连接的客户端线程而使用的变量 in 都被新的线程重新定义了。
解决的办法是为每个线程创建一个 Scanner对象 in.

服务端代码修改一下,楼主试试:

Java code
@Overridepublic void run() {// TODO Auto-generated method stubtry {//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();}}} 

读书人网 >J2SE开发

热点推荐