已有101人关注
第19章 网络通信问题 例19.2,,19.3疑问
发表在Java图书答疑 2016-06-16
是否精华
版块置顶:
实践与练习 编写以下聊天室程序 运行后为什么没有阻塞,但是书中例19.2 和19.3 的程序却可以阻塞。

服务器端:

import java.awt.BorderLayout;
import java.awt.Container;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.ServerSocket;
import java.net.Socket;

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

public class ChatServer extends JFrame implements Runnable{
private static final long serialVersionUID = 1L;

private ServerSocket server;
private Socket socket;
private PrintWriter writer;
private BufferedReader reader;
private JTextArea ta;
private JScrollPane sp;
private JTextField tf;
private JButton send,cancel;
private JPanel south;
private Container c;

public ChatServer() {
ta=new JTextArea();
tf=new JTextField(20);
tf.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
ta.append("你 说:\n");
ta.append("        "+tf.getText());
send.doClick();
}
});
send=new JButton("发送");
send.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
sendMessage();
}
});
send.setEnabled(false);
cancel=new JButton("取消");
cancel.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent arg0) {
tf.setText("");
tf.requestFocus();
}
});
sp=new JScrollPane(ta);
sp.setVerticalScrollBarPolicy(ScrollPaneConstants.VERTICAL_SCROLLBAR_ALWAYS);

south=new JPanel();
south.add(tf);
south.add(send);
south.add(cancel);

c=getContentPane();
c.add(sp, BorderLayout.CENTER);
c.add(south, BorderLayout.SOUTH);

setTitle("正在与 客户端 聊天");
setSize(400, 300);
setResizable(false);
setLocationRelativeTo(null);
setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
setVisible(true);
}

private void getMessage(){
while(true){
try {
if(reader==null){
reader=new BufferedReader(new InputStreamReader(socket.getInputStream()));
}
ta.append("客户端 说:\n");
ta.append("        "+reader.readLine()+"\n");
tf.requestFocus();
} catch (Exception e) {

} finally{
try {
reader.close();
} catch (Exception e2) {

}
}
}
}

private void sendMessage(){
try {
if(writer==null){
writer=new PrintWriter(socket.getOutputStream(), true);
}
writer.println(tf.getText());
tf.requestFocus();
} catch (Exception e) {

} finally{
try {
writer.close();
} catch (Exception e2) {

}
}
}

private void connect(){
try {
server=new ServerSocket(9999);
ta.append("成功创建服务器套接字\n");
tf.requestFocus();
socket=server.accept();
ta.append("成功与客户端建立连接\n");
tf.requestFocus();
new Thread(this).start();
send.setEnabled(true);
} catch (Exception e) {

}
}

public void run(){
getMessage();
}

public static void main(String[] args) {
new ChatServer().connect();
}
}


客户端:

import java.awt.BorderLayout;
import java.awt.Container;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.Socket;

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

public class ChatClient extends JFrame implements Runnable{
private static final long serialVersionUID = 1L;

private Socket socket;
private PrintWriter writer;
private BufferedReader reader;
private JTextArea ta;
private JScrollPane sp;
private JTextField tf;
private JButton send,cancel;
private JPanel south;
private Container c;

public ChatClient() {
ta=new JTextArea();
tf=new JTextField(20);
tf.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
send.doClick();
}
});
send=new JButton("发送");
send.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
ta.append("你 说:\n");
ta.append("        "+tf.getText());
sendMessage();
}
});
send.setEnabled(false);
cancel=new JButton("取消");
cancel.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent arg0) {
tf.setText("");
tf.requestFocus();
}
});
sp=new JScrollPane(ta);
sp.setVerticalScrollBarPolicy(ScrollPaneConstants.VERTICAL_SCROLLBAR_ALWAYS);

south=new JPanel();
south.add(tf);
south.add(send);
south.add(cancel);

c=getContentPane();
c.add(sp, BorderLayout.CENTER);
c.add(south, BorderLayout.SOUTH);

setTitle("正在与 服务器 聊天");
setSize(400, 300);
setResizable(false);
setLocationRelativeTo(null);
setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
setVisible(true);
}

private void getMessage(){
while(true){
try {
if(reader==null){
reader=new BufferedReader(new InputStreamReader(socket.getInputStream()));
}
ta.append("服务器 说:\n");
ta.append("        "+reader.readLine()+"\n");
tf.requestFocus();
} catch (Exception e) {

} finally{
try {
reader.close();
} catch (Exception e2) {

}
}
}
}

private void sendMessage(){
try {
if(writer==null){
writer=new PrintWriter(socket.getOutputStream(), true);
}
writer.println(tf.getText());
tf.requestFocus();
} catch (Exception e) {

} finally{
try {
writer.close();
} catch (Exception e2) {

}
}
}

private void connect(){
try {
ta.append("尝试与服务器建立连接...\n");
tf.requestFocus();
socket=new Socket("127.0.0.1", 9999);
ta.append("成功与服务器建立连接\n");
tf.requestFocus();
new Thread(this).start();
send.setEnabled(true);
} catch (Exception e) {

}
}

public void run(){
getMessage();
}

public static void main(String[] args) {
new ChatClient().connect();
}

}


例19.2的服务器端代码:

import java.io.*;
import java.net.*;

public class ServerTCP {
BufferedReader reader;
ServerSocket server;
Socket socket;

public static void main(String[] args) {
ServerTCP server=new ServerTCP();
server.getServer();
}

void getServer(){
try {
server=new ServerSocket(8998);
System.out.println("服务器套接字创建成功");
while(true){
System.out.println("等待客户机连接...");
socket=server.accept();
reader=new BufferedReader(new InputStreamReader(socket.getInputStream()));
getClientMessage();
}
} catch (Exception e) {

}
}

void getClientMessage(){
try {
while(true){
System.out.println("客户机:"+reader.readLine());
}
} catch (Exception e) {

}
try {
if(reader!=null){
reader.close();
}
if(socket!=null){
socket.close();
}
} catch (Exception e) {

}
}
}


查看资料发现readLine()方法并不会阻塞 为什么书中的例子getClientMessage()方法似乎是发生了阻塞呢。我的程序代码哪里发生了错误,一运行CPU马上100%。
分享到:
精彩评论 1
静心_mrkj
学分:0 LV1
2016-06-17
沙发
你需要启动两次eclipse(注意:workspace必须是不相同的。且一个eclipse创建服务器,另一个eclipse创建客户端),然后先启动服务器,再启动客户端。
首页上一页 1 下一页尾页 1 条记录 1/1页
手机同步功能介绍
友情提示:以下图书配套资源能够实现手机同步功能
明日微信公众号
明日之星 明日之星编程特训营
客服热线(每日9:00-17:00)
400 675 1066
mingrisoft@mingrisoft.com
吉林省明日科技有限公司Copyright ©2007-2022,mingrisoft.com, All Rights Reserved长春市北湖科技开发区盛北大街3333号长春北湖科技园项目一期A10号楼四、五层
吉ICP备10002740号-2吉公网安备22010202000132经营性网站备案信息 营业执照