当前位置: 技术问答>java相关
Java 网络编程---SL275练习题疑惑
来源: 互联网 发布时间:2015-08-04
本文导语: SL275---Module16练习题1 用Socket编写网络聊天程序,以下是源代码,为求完整,分几部分贴出,各位大虾 不要嫌长,我的问题是: ChatServer如何接受Client谈话内容并转发给所有其他聊天的Client.尤其是ChatServer中Connection类的...
SL275---Module16练习题1
用Socket编写网络聊天程序,以下是源代码,为求完整,分几部分贴出,各位大虾
不要嫌长,我的问题是:
ChatServer如何接受Client谈话内容并转发给所有其他聊天的Client.尤其是ChatServer中Connection类的run(),没有循环监听,怎么能实现?
疑问部分代码有/**************************/标明,请各位大虾解释,不甚感激!
//ChatServer代码
import java.io.*;
import java.net.*;
import java.util.*;
import java.applet.*;
public class ChatServer implements Runnable {
public final static int DEFAULT_PORT = 2000;
public final static int DEFAULT_MAX_BACKLOG = 5;
public final static int DEFAULT_MAX_CONNECTIONS = 20;
public final static String DEFAULT_HOST_FILE = "hosts.txt";
public final static String DEFAULT_SOUND_FILE = "file:gong.au";
public final static String MAGIC = "Yippy Skippy";
private String magic = MAGIC;
private int port = DEFAULT_PORT;
private int backlog = DEFAULT_MAX_BACKLOG;
private int numConnections = 0;
private int maxConnections = DEFAULT_MAX_CONNECTIONS;
private String hostfile = DEFAULT_HOST_FILE;
private String soundfile = DEFAULT_SOUND_FILE;
private Vector connections = null;
private AudioClip connectSound = null;
private Hashtable hostInfo = new Hashtable(15);
public static void main(String[] args) {
ChatServer cs = new ChatServer();
cs.go();
}
public void go()
{
String portString = System.getProperty("port");
if(portString != null) port = Integer.parseInt(portString);
String backlogString = System.getProperty("backlog");
if(backlogString != null) backlog = Integer.parseInt(backlogString);
String hostFileString = System.getProperty("hostfile");
if(hostFileString != null) hostfile = hostFileString;
String soundFileString = System.getProperty("soundfile");
if(soundFileString != null) soundfile = soundFileString;
String magicString = System.getProperty("magic");
if(magicString != null) magic = magicString;
String connections = System.getProperty("connections");
if(connections != null) maxConnections = Integer.parseInt(connections);
this.connections = new Vector(maxConnections);
System.out.println("Server settings:ntPort="+port+"ntMax Backlog="+
backlog+"ntMax Connections="+maxConnections+
"ntHost File="+hostfile+"ntSound File="+soundfile);
createHostList();
try {
URL sound = new URL(/tech-qa-java/soundfile/index.html);
connectSound = Applet.newAudioClip(sound);
} catch(Exception e) { e.printStackTrace(); }
this.port = port;
Thread t = new Thread(this);
t.start();
}
private void createHostList() {
File hostFile = new File(hostfile);
try {
System.out.println("Attempting to read hostfile hosts.txt: ");
FileInputStream fis = new FileInputStream(hostFile);
InputStreamReader isr = new InputStreamReader(fis);
BufferedReader br = new BufferedReader(isr);
String aLine = null;
while((aLine = br.readLine()) != null)
{
int spaceIndex = aLine.indexOf(' ');
if(spaceIndex == -1) {
System.out.println("Invalid line in host file: "+aLine);
continue;
}
String host = aLine.substring(0,spaceIndex);
String student = aLine.substring(spaceIndex+1);
System.out.println("Read: "+student+"@"+host);
hostInfo.put(host,student);
}
}
catch(Exception e) { e.printStackTrace(); }
}
public void run()
{
ServerSocket serverSocket = null;
Socket communicationSocket;
try
{
System.out.println("Attempting to start server...");
serverSocket = new ServerSocket(port,backlog);
}
catch (IOException e)
{
System.out.println("Error starting server: Could not open port "+port);
e.printStackTrace();
System.exit(-1);
}
System.out.println ("Started server on port "+port);
// Run the listen/accept loop forever
while (true)
{
try
{
// Wait here and listen for a connection
communicationSocket = serverSocket.accept();
HandleConnection(communicationSocket);
}
catch (Exception e)
{
System.out.println("Unable to spawn child socket.");
e.printStackTrace();
}
}
}
public void HandleConnection(Socket connection)
{
synchronized(this)
{
while(numConnections == maxConnections)
{
try { wait(); }
catch(Exception e) { e.printStackTrace(); }
}
}
numConnections++;
Connection con = new Connection(connection);
Thread t = new Thread(con);
t.start();
connections.addElement(con);
}
public synchronized void connectionClosed(Connection connection)
{
connections.removeElement(connection);
numConnections--;
notify();
}
public void sendToAllClients(String message)
{
Enumeration cons = connections.elements();
while(cons.hasMoreElements())
{
Connection c = (Connection)cons.nextElement();
c.sendMessage(message);
}
}
class Connection implements Runnable
{
private Socket communicationSocket = null;
private OutputStreamWriter out = null;
private BufferedReader in = null;
public void run()
{
OutputStream socketOutput = null;
InputStream socketInput = null;
try
{
socketOutput = communicationSocket.getOutputStream();
out = new OutputStreamWriter(socketOutput);
socketInput = communicationSocket.getInputStream();
in = new BufferedReader(new InputStreamReader(socketInput));
InetAddress address = communicationSocket.getInetAddress();
String hostname = address.getHostName();
String welcome =
"Connection made from host: "+hostname+"nEverybody say hello";
String student = (String)(hostInfo.get(hostname));
if(student != null) welcome += " to "+student;
welcome+="!n";
ChatServer.this.sendToAllClients(welcome);
System.out.println("Connection made "+student+"@"+hostname);
sendMessage("Welcome "+student+" the passphrase is "+magic+"n");
String input = null;
while((input = in.readLine()) != null) {
if(input.indexOf(magic) != -1 && connectSound != null)
{
connectSound.play();
sendMessage("Congratulations "+student+" you sent the passphrase!n");
System.out.println(student+" sent the passphrase!");
}
else ChatServer.this.sendToAllClients(input+"n");
}
}
catch(Exception e) { }
finally
{
try
{
if(in != null) in.close();
if(out != null) out.close();
communicationSocket.close();
}
catch(Exception e) { e.printStackTrace(); }
ChatServer.this.connectionClosed(this);
}
}
public Connection(Socket s)
{
communicationSocket = s;
}
public void sendMessage(String message)
{
try
{
out.write(message);
out.flush();
}
catch(Exception e) { e.printStackTrace(); }
}
}
}
用Socket编写网络聊天程序,以下是源代码,为求完整,分几部分贴出,各位大虾
不要嫌长,我的问题是:
ChatServer如何接受Client谈话内容并转发给所有其他聊天的Client.尤其是ChatServer中Connection类的run(),没有循环监听,怎么能实现?
疑问部分代码有/**************************/标明,请各位大虾解释,不甚感激!
//ChatServer代码
import java.io.*;
import java.net.*;
import java.util.*;
import java.applet.*;
public class ChatServer implements Runnable {
public final static int DEFAULT_PORT = 2000;
public final static int DEFAULT_MAX_BACKLOG = 5;
public final static int DEFAULT_MAX_CONNECTIONS = 20;
public final static String DEFAULT_HOST_FILE = "hosts.txt";
public final static String DEFAULT_SOUND_FILE = "file:gong.au";
public final static String MAGIC = "Yippy Skippy";
private String magic = MAGIC;
private int port = DEFAULT_PORT;
private int backlog = DEFAULT_MAX_BACKLOG;
private int numConnections = 0;
private int maxConnections = DEFAULT_MAX_CONNECTIONS;
private String hostfile = DEFAULT_HOST_FILE;
private String soundfile = DEFAULT_SOUND_FILE;
private Vector connections = null;
private AudioClip connectSound = null;
private Hashtable hostInfo = new Hashtable(15);
public static void main(String[] args) {
ChatServer cs = new ChatServer();
cs.go();
}
public void go()
{
String portString = System.getProperty("port");
if(portString != null) port = Integer.parseInt(portString);
String backlogString = System.getProperty("backlog");
if(backlogString != null) backlog = Integer.parseInt(backlogString);
String hostFileString = System.getProperty("hostfile");
if(hostFileString != null) hostfile = hostFileString;
String soundFileString = System.getProperty("soundfile");
if(soundFileString != null) soundfile = soundFileString;
String magicString = System.getProperty("magic");
if(magicString != null) magic = magicString;
String connections = System.getProperty("connections");
if(connections != null) maxConnections = Integer.parseInt(connections);
this.connections = new Vector(maxConnections);
System.out.println("Server settings:ntPort="+port+"ntMax Backlog="+
backlog+"ntMax Connections="+maxConnections+
"ntHost File="+hostfile+"ntSound File="+soundfile);
createHostList();
try {
URL sound = new URL(/tech-qa-java/soundfile/index.html);
connectSound = Applet.newAudioClip(sound);
} catch(Exception e) { e.printStackTrace(); }
this.port = port;
Thread t = new Thread(this);
t.start();
}
private void createHostList() {
File hostFile = new File(hostfile);
try {
System.out.println("Attempting to read hostfile hosts.txt: ");
FileInputStream fis = new FileInputStream(hostFile);
InputStreamReader isr = new InputStreamReader(fis);
BufferedReader br = new BufferedReader(isr);
String aLine = null;
while((aLine = br.readLine()) != null)
{
int spaceIndex = aLine.indexOf(' ');
if(spaceIndex == -1) {
System.out.println("Invalid line in host file: "+aLine);
continue;
}
String host = aLine.substring(0,spaceIndex);
String student = aLine.substring(spaceIndex+1);
System.out.println("Read: "+student+"@"+host);
hostInfo.put(host,student);
}
}
catch(Exception e) { e.printStackTrace(); }
}
public void run()
{
ServerSocket serverSocket = null;
Socket communicationSocket;
try
{
System.out.println("Attempting to start server...");
serverSocket = new ServerSocket(port,backlog);
}
catch (IOException e)
{
System.out.println("Error starting server: Could not open port "+port);
e.printStackTrace();
System.exit(-1);
}
System.out.println ("Started server on port "+port);
// Run the listen/accept loop forever
while (true)
{
try
{
// Wait here and listen for a connection
communicationSocket = serverSocket.accept();
HandleConnection(communicationSocket);
}
catch (Exception e)
{
System.out.println("Unable to spawn child socket.");
e.printStackTrace();
}
}
}
public void HandleConnection(Socket connection)
{
synchronized(this)
{
while(numConnections == maxConnections)
{
try { wait(); }
catch(Exception e) { e.printStackTrace(); }
}
}
numConnections++;
Connection con = new Connection(connection);
Thread t = new Thread(con);
t.start();
connections.addElement(con);
}
public synchronized void connectionClosed(Connection connection)
{
connections.removeElement(connection);
numConnections--;
notify();
}
public void sendToAllClients(String message)
{
Enumeration cons = connections.elements();
while(cons.hasMoreElements())
{
Connection c = (Connection)cons.nextElement();
c.sendMessage(message);
}
}
class Connection implements Runnable
{
private Socket communicationSocket = null;
private OutputStreamWriter out = null;
private BufferedReader in = null;
public void run()
{
OutputStream socketOutput = null;
InputStream socketInput = null;
try
{
socketOutput = communicationSocket.getOutputStream();
out = new OutputStreamWriter(socketOutput);
socketInput = communicationSocket.getInputStream();
in = new BufferedReader(new InputStreamReader(socketInput));
InetAddress address = communicationSocket.getInetAddress();
String hostname = address.getHostName();
String welcome =
"Connection made from host: "+hostname+"nEverybody say hello";
String student = (String)(hostInfo.get(hostname));
if(student != null) welcome += " to "+student;
welcome+="!n";
ChatServer.this.sendToAllClients(welcome);
System.out.println("Connection made "+student+"@"+hostname);
sendMessage("Welcome "+student+" the passphrase is "+magic+"n");
String input = null;
while((input = in.readLine()) != null) {
if(input.indexOf(magic) != -1 && connectSound != null)
{
connectSound.play();
sendMessage("Congratulations "+student+" you sent the passphrase!n");
System.out.println(student+" sent the passphrase!");
}
else ChatServer.this.sendToAllClients(input+"n");
}
}
catch(Exception e) { }
finally
{
try
{
if(in != null) in.close();
if(out != null) out.close();
communicationSocket.close();
}
catch(Exception e) { e.printStackTrace(); }
ChatServer.this.connectionClosed(this);
}
}
public Connection(Socket s)
{
communicationSocket = s;
}
public void sendMessage(String message)
{
try
{
out.write(message);
out.flush();
}
catch(Exception e) { e.printStackTrace(); }
}
}
}
|
不太懂:
“input = in.readLine()) != null很容易满足,导致该线程结束。”
BufferedReader.readLine()只有在读到流结束符时才返回null,这只有客户端的输出流调用finish()或者close()方法,你才能读到。注意:用户仅仅敲击回车键,那in.readLine()读取的是回车苻,不是流结束符。
“input = in.readLine()) != null很容易满足,导致该线程结束。”
BufferedReader.readLine()只有在读到流结束符时才返回null,这只有客户端的输出流调用finish()或者close()方法,你才能读到。注意:用户仅仅敲击回车键,那in.readLine()读取的是回车苻,不是流结束符。
|
heifei()说得对呀,只有流被关闭是readLine才返回null。