求大侠解救!看了两天都没解决!

一个流浪书生 2015-11-10 07:50:14
这是一个以服务端为面板的几个客户端的聊天界面程序;就像QQ群里的群聊一样;但是就在跟服务端进行交互的时候就出错了;运行到 ServerThread.run()这里面就不停br.readLine()了;之前写的跟服务端交互的程序也都没有出错;为什么会在while(true)这里就不停循环呢?不是应该在br.readLine()这里停住吗?我看老师写的也是这样啊?!我是看的视频教程!



/**
*这个是服务端
*
*/
package Chat02;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.ServerSocket;
import java.net.Socket;
import java.net.SocketException;

public class Server {

public static final String HOST = "127.0.0.1";
public static final int PORT = 2233;
/**
* @param args
*/
public static void main(String[] args) {

new Server().startup();
}

private void startup(){
ServerSocket ss = null;
try {
ss = new ServerSocket(PORT);
while(true){
Socket s = ss.accept();
// new Thread(new ServerThread(s)).start();
Thread t = new Thread(new ServerThread(s));
t.start();
}
} catch (IOException e) {
e.printStackTrace();
} finally{
try {
if(ss!=null) ss.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}

private class ServerThread implements Runnable{
private Socket s;
private BufferedReader br;
private PrintWriter out;
private String name;

public ServerThread(Socket s) throws SocketException,IOException{
this.s = s;
br = new BufferedReader(new InputStreamReader(s.getInputStream()));
out = new PrintWriter(s.getOutputStream(),true);
// name = br.readLine();
name += "["+s.getInetAddress().getHostAddress()+"]";
System.out.println(name + "连接了");
}

public void run(){
while(true){
try {
String str = br.readLine();
System.out.println(name + ":" + str);
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}


/**
* 这个是客户端,聊天界面 跟服务端交互的界面
*/
package Chat02;

import java.awt.BorderLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
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.DefaultListModel;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JList;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.JTextField;
/**
* 聊天页面
* @author sunsichang
*
*/
public class Client extends JFrame {
/**
* 聊天面板
*/
private JTextArea jta;
/**
* 输入框
*/
private JTextField jtf;
private JPanel jp;
/**
* 发送按钮
*/
private JButton jb;
private JScrollPane jsp1,jsp2;
/**
* 在线人数列表
*/
private JList list;
/**
* 列表元素集合
*/
private DefaultListModel<String> model;
private String name;

private Socket s;
private BufferedReader br;
private PrintWriter out;

public Client(String name){
this.setLocation(100,100);
this.setDefaultCloseOperation(EXIT_ON_CLOSE);
this.setSize(800,600);
this.setResizable(false);

this.name = name;
this.setTitle("网络聊天["+name+"]");

jta = new JTextArea();
jsp1 = new JScrollPane(jta);
jtf = new JTextField(35);
jb = new JButton("发送");
jb.addActionListener(new BtnClick());

model = new DefaultListModel<String>();
list = new JList(model);
list.setFixedCellWidth(100);
jsp2 = new JScrollPane(list);

jp = new JPanel();
this.add(jsp1);
jp.add(jtf); jp.add(jb);

this.add(jp,BorderLayout.SOUTH);
this.add(jsp2,BorderLayout.WEST);

jtf.addKeyListener(new KeyClick());

connect();

this.setVisible(true);
}
/**
* 连接到服务器
*/
private void connect() {
try {
s = new Socket(Server.HOST, Server.PORT);
br = new BufferedReader(new InputStreamReader(s.getInputStream()));
out = new PrintWriter(s.getOutputStream(),true);
out.println(name);
} catch (UnknownHostException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally{
try {
if(s!=null) s.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}

/**
* 增加事件,点击回车发送消息到面板和服务器
* @author sunsichang
*
*/
private class KeyClick extends KeyAdapter{
@Override
public void keyPressed(KeyEvent e) {
if(e.getKeyCode()==KeyEvent.VK_ENTER)
send();
}
}
/**
* 发送消息到服务器
*/
public void send(){
String word = jtf.getText();
if (word == null || word.trim().equals("")) {
return;
}
model.addElement(word);
jta.setText(jta.getText() + name + ":" + word + "\n");
jtf.setText("");
out.println(word);
}

/**
* 点击“发送”按钮把文本发送到控制台 和服务器
* @author sunsichang
*
*/
private class BtnClick implements ActionListener{

@SuppressWarnings("deprecation")
public void actionPerformed(ActionEvent e) {
if(e.getSource() == jb){
send();
Object[] vals = list.getSelectedValues();
for(Object o:vals){
System.out.println(o);
}
}
}

}
}



/**
* 这个是客户端登录界面,跟服务端不进行交互,只把nam传给Client
*/
package Chat02;

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

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

/**
* 登录窗口
* @author sunsichang
*
*/
@SuppressWarnings("serial")
public class LoginFrame extends JFrame {
private JLabel jl;
private JButton jb;
private JTextField jtf;

public static void main(String[] args) {
new LoginFrame();
}

public void close(){
this.setVisible(false);
}

public LoginFrame(){
this.setLocation(100, 100);
this.setSize(500,130);
this.setTitle("用户登录");
this.setResizable(false);
this.setDefaultCloseOperation(EXIT_ON_CLOSE);
this.setLayout(new FlowLayout());

jl = new JLabel("输入用户名:");
jtf = new JTextField(22);
jb = new JButton("连接");
jb.addActionListener(new ActionListener() {

@Override
public void actionPerformed(ActionEvent e) {
String name = jtf.getText();
if(name==null||name.trim().equals("")){
JOptionPane.showMessageDialog(null, "请输入用户名");
return;
}
new Client(name);
close();
}
});
this.add(jl); this.add(jtf); this.add(jb);


this.setVisible(true);
}



}
...全文
788 8 打赏 收藏 转发到动态 举报
写回复
用AI写文章
8 条回复
切换为时间正序
请发表友善的回复…
发表回复
  • 打赏
  • 举报
回复
亲,你64行那个while(true)的循环退出条件是啥? 52行private String name;不需要初始化吗? 只要tcp receive buffer里有内容,readline自然揍读了。 ServerSocket放在try-with-resource block里揍可以省去close了, 看看tutorial呗: https://docs.oracle.com/javase/tutorial/networking/sockets/clientServer.html
一个流浪书生 2015-11-11
  • 打赏
  • 举报
回复
我要再等等!一定会解决的!
一个流浪书生 2015-11-10
  • 打赏
  • 举报
回复
引用 4 楼 w809ccc 的回复:
// 因为读到了流末尾,所以不停的返回null,不会停止。run部分的代码可以改为 public void run() { while (true) { try { String str; while ((str = br.readLine()) != null) System.out.println(name + ":" + str); } catch (IOException e) { e.printStackTrace(); } } }
复制了再试一次,还是一直null..不过这次是name变成null了。从第二次起,
w809ccc 2015-11-10
  • 打赏
  • 举报
回复
// 因为读到了流末尾,所以不停的返回null,不会停止。run部分的代码可以改为 public void run() { while (true) { try { String str; while ((str = br.readLine()) != null) System.out.println(name + ":" + str); } catch (IOException e) { e.printStackTrace(); } } }
一个流浪书生 2015-11-10
  • 打赏
  • 举报
回复
嗯,再等等;本来今天是要把Socket编程跟String正则表达式写完的。 这个是输入用户名后把name传给Client ,然后Client再传给Server,结果直接运行到run()这里了,还不停地执行br.readLine();
一个流浪书生 2015-11-10
  • 打赏
  • 举报
回复
引用 1 楼 scmod 的回复:
没抛异常? 按理br.readLine()会阻塞停住等输入的... 图形不熟..不知道是不是图形输入框会不停触发什么东西
我也觉得奇怪;之前的服务端跟客户端之前的程序会在br.readLine()这边停住;但这个就不会;这个程序是可以运行的 不信可以复制一下到你的电脑试试?
scmod 2015-11-10
  • 打赏
  • 举报
回复
没抛异常? 按理br.readLine()会阻塞停住等输入的... 图形不熟..不知道是不是图形输入框会不停触发什么东西
你想当“李逍遥”式的“大侠”吗? 这里无需计算机基础,无需编程经验,你也不必是计算机专业的在校大学生....只要爱好游戏,怀揣梦想! 有一定自主学习能力,跟着刘老师从“编程小白”修炼为游戏研发“大虾”吧!!!学习好Unity,其先决条件是一定要有稳固、扎实的编程基础!课程 《C# For Unity系列之入门篇》配套学习资料链接:http://pan.baidu.com/s/1gflxreN 密码:sou5;刘老师讲Unity学员群(2) 497429806一、热更新系列(技术含量:中高级):A:《lua热更新技术中级篇》https://edu.csdn.net/course/detail/27087B:《热更新框架设计之Xlua基础视频课程》https://edu.csdn.net/course/detail/27110C:《热更新框架设计之热更流程与热补丁技术》https://edu.csdn.net/course/detail/27118D:《热更新框架设计之客户端热更框架(上)》https://edu.csdn.net/course/detail/27132E:《热更新框架设计之客户端热更框架(中)》https://edu.csdn.net/course/detail/27135F:《热更新框架设计之客户端热更框架(下)》https://edu.csdn.net/course/detail/27136二:框架设计系列(技术含量:中级): A:《游戏UI界面框架设计系列视频课程》https://edu.csdn.net/course/detail/27142B:《Unity客户端框架设计PureMVC篇视频课程(上)》https://edu.csdn.net/course/detail/27172C:《Unity客户端框架设计PureMVC篇视频课程(下)》https://edu.csdn.net/course/detail/27173D:《AssetBundle框架设计_框架篇视频课程》https://edu.csdn.net/course/detail/27169三、Unity脚本从入门到精通(技术含量:初级)A:《C# For Unity系列之入门篇》https://edu.csdn.net/course/detail/4560B:《C# For Unity系列之基础篇》https://edu.csdn.net/course/detail/4595C: 《C# For Unity系列之中级篇》https://edu.csdn.net/course/detail/24422D:《C# For Unity系列之进阶篇》https://edu.csdn.net/course/detail/24465四、虚拟现实(VR)与增强现实(AR):(技术含量:初级)A:《虚拟现实之汽车仿真模拟系统 》https://edu.csdn.net/course/detail/26618五、Unity基础课程系列(技术含量:初级) A:《台球游戏与FlappyBirds—Unity快速入门系列视频课程(第1部)》 https://edu.csdn.net/course/detail/24643B:《太空射击与移动端发布技术-Unity快速入门系列视频课程(第2部)》https://edu.csdn.net/course/detail/24645 C:《Unity ECS(二) 小试牛刀》https://edu.csdn.net/course/detail/27096六、Unity ARPG课程(技术含量:初中级):A:《MMOARPG地下守护神_单机版实战视频课程(上部)》https://edu.csdn.net/course/detail/24965B:《MMOARPG地下守护神_单机版实战视频课程(中部)》https://edu.csdn.net/course/detail/24968C:《MMOARPG地下守护神_单机版实战视频课程(下部)》https://edu.csdn.net/course/detail/24979

62,614

社区成员

发帖
与我相关
我的任务
社区描述
Java 2 Standard Edition
社区管理员
  • Java SE
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧