⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 chatserver.java

📁 有不好之处请帮忙
💻 JAVA
字号:
import java.net.*;
import java.io.*;
import java.util.*;

/***************************************************************************
*
*   Created by:  Christian Ricci
*   Started:     March 17, 2000
*   See also:    chatadmin.java, chatapplet.java
*  
*   My chatserver program is designed to be used with a chat applet.  
*   However, there is no reason a person with a telnet client, connecting 
*   to the configured port couldn't utilize this application.
*
*   There are three classes in this .java file: chatserver, broadcaster and
*   listener.
*
***************************************************************************/

/***************************************************************************
* 
* - chatserver, parent class.  Listens for a connection on the comm
*   port, passed in the argument list.  An incoming connection causes
*   this application to spawn a listener and broadcaster thread.  There
*   can be many simultaneous instances of this application running at
*   any given time.
*
***************************************************************************/

public class ChatServer {

/***************************************************************************
*   method: swrite -- rudimentary communications for the chatserver class
***************************************************************************/

    public static void swrite(Socket sock, String str) throws Exception {

	OutputStream outStream = sock.getOutputStream();
	outStream.write(str.getBytes());
	outStream.flush();

    }

/***************************************************************************
*   method: main 
***************************************************************************/

    public static void main(String args[]) throws Exception {

	//
	// Communications
	//

	Listener listenHandle   = null;
	Broadcaster broadHandle = null;
	PipedInputStream in     = new PipedInputStream();
	PipedOutputStream out   = new PipedOutputStream(in);
	ServerSocket server     = new ServerSocket(Integer.parseInt(args[0]));
	InputStream inStream;
	BufferedReader inReader;
	Socket sock;

	//
	// tmpVars and output strings
	//

	int counter             = -1;
	long tmpKey;
	String name, systemOut;

	System.out.println("Chat Server Running");
	while (true) {

		//
		// Get, open new connection
		//

		sock = server.accept();
		inReader = new BufferedReader(
			   new InputStreamReader(
			     sock.getInputStream()));

		//
		// Get name of participant
		//

		swrite(sock, "Name? ");
		name = inReader.readLine();
		tmpKey = (new Date()).getTime();

		//	
		// Either start threads or add connections
		//

		if (counter == -1) {

			broadHandle = 
			  new Broadcaster(sock, in, tmpKey, name);
			listenHandle = 
			  new Listener(sock, out, tmpKey, name, broadHandle);

			Thread t1 = new Thread(listenHandle);
			Thread t2 = new Thread(broadHandle);

			t1.start();
			t2.start();

		} else {

			listenHandle.addSock(sock, tmpKey, name);
			broadHandle.addSock(sock, tmpKey, name);

		}

		//
		// Get current number of connections
		//

		counter = listenHandle.numSocks();

		systemOut = "Added User : " + name + " (" + counter + ")";
		System.out.println(systemOut);

	}

    }

}


/***************************************************************************
* 
* - Broadcaster, output thread.  Spawned by chatserver.  Keeps a hash-
*   table of the outputstreams associated with this each connection.
*   A PipedInputStream passes communications to this thread class
*   (spawned as a thread) from the Listener thread.  When commun-
*   ications passes thru this pipe, it enumerates thru the hashtable,
*   sending the message and user name to each connection.
*
***************************************************************************/

class Broadcaster implements Runnable {

    //
    // Global vars
    //

    Hashtable sockHash = new Hashtable();
    InputStream in;
    private Socket sock;
    private PrintWriter ostr;

/***************************************************************************
*   method: constructor -- call addSock, setup InputStream
***************************************************************************/

    public Broadcaster(Socket sock, InputStream in, long i, String name) 
	throws IOException {

	this.in = in;
	addSock(sock, i, name);

    }
    
/***************************************************************************
*   method: bCast -- Performs actual output (to a PrintWriter, see note).
***************************************************************************/

    private void bCast(String s) throws IOException {
	PrintWriter os;

	for (Enumeration e = sockHash.elements() ; e.hasMoreElements() ;) {

		os = (PrintWriter)e.nextElement();
		os.println(s);
		os.flush();

	}

    }

/***************************************************************************
*   method: addSock -- Adds a new connection to the hashtable, bCast user.
***************************************************************************/

    public void addSock(Socket sock, long i, String name) 
	throws IOException {

	ostr = new PrintWriter(new OutputStreamWriter(sock.getOutputStream()));
	sockHash.put(Long.toString(i), ostr);

	try {

		bCast(name + " has joined.");

	}
	catch (Exception e) {

		e.printStackTrace();

	}

    }

/***************************************************************************
*   method: delSock -- Removes a connection in the hashtable.
***************************************************************************/

    public void delSock(Object hKey) throws IOException {

	sockHash.remove(hKey);

    }

/***************************************************************************
*   method: run -- Main thread activity, loopty
***************************************************************************/

    public void run() {

	BufferedReader istr = new BufferedReader(new InputStreamReader(in));
	try {
		while (true) {
			bCast(istr.readLine());
		}
	}
	catch (Exception e) {
		e.printStackTrace();
	}

    }

}


/***************************************************************************
*
* - Listener, input thread.  Like the Broadcaster thread, the Listener
*   thread maintains a hashtable for each of the current connections.
*   It enumerates thru the connections, checking for incoming messages
*   and passes them through a PipedOutputStream to the Broadcaster
*   thread.
*
***************************************************************************/

class Listener implements Runnable {

    //
    // Global vars
    //

    Hashtable sockHash = new Hashtable();
    Hashtable nameHash = new Hashtable();
    OutputStream out;
    Broadcaster broadHandle;
    private Socket sock;
    private BufferedReader istr;

/***************************************************************************
*   method: constructor -- call addSock, setup connection to Broadcaster
***************************************************************************/

    public Listener(Socket sock, OutputStream out, 
	long i, String name, Broadcaster broadHandle) throws IOException {

	this.broadHandle = broadHandle;
	this.out = out;
	addSock(sock, i, name);

    }

/***************************************************************************
*   method: addSock -- Adds a new connection to the hashtable.
***************************************************************************/

    public void addSock(Socket sock, long i, String name) throws IOException {

	istr = new BufferedReader(new InputStreamReader(sock.getInputStream()));
	sockHash.put(Long.toString(i), istr);
	nameHash.put(Long.toString(i), name);

    }

/***************************************************************************
*   method: numSocks -- Returns number of known connections.
***************************************************************************/

    public int numSocks() {

	return sockHash.size();

    }

/***************************************************************************
*   method: delSock -- Removes a connection in the hashtable.  Output 
*                      disconnect.
***************************************************************************/

    public void delSock(Object hKey) throws IOException {

	String systemOut;
	String tmpName = (String)nameHash.get(hKey);
	String tmpStr = tmpName + " has left.\n";

	//
	// Connection over to broadcaster thread
	//

	broadHandle.delSock(hKey);	

	//
	// Close socket
	//

	BufferedReader tmpBfr = (BufferedReader)sockHash.get(hKey);
	tmpBfr.close();

	//
	// Clean out hashtable entries
	//

	sockHash.remove(hKey);
	nameHash.remove(hKey);

	//
	// Broadcast departure
	//

	out.write(tmpStr.getBytes());

	systemOut = "Removed User : " + tmpName + " (" + nameHash.size() + ")";
	System.out.println(systemOut);

    }

/***************************************************************************
*   method: run -- Main thread activity, loopty
***************************************************************************/

    public void run() {

	String tmpStr, tmpName, tmpInput;
	String exitStr = new String("exit");
	Object tmpKey;
	BufferedReader tmpBfr;

	try {

	while (true) {

	//
	// Loop thru hash table looking for input that is ready to be
	// posted.
	//

	for (Enumeration e = sockHash.keys() ; e.hasMoreElements() ;) {
		tmpKey = e.nextElement();
		tmpBfr = (BufferedReader)sockHash.get(tmpKey);
		if (tmpBfr.ready()) {
			tmpInput = tmpBfr.readLine();
			if (tmpInput.compareToIgnoreCase(exitStr) == 0) {
				delSock(tmpKey);
			} else if (tmpInput != "") {
				tmpName = (String)nameHash.get(tmpKey);
				tmpStr = tmpName + " : " + tmpInput + "\n";
				out.write(tmpStr.getBytes());
			}
		}
	}

	}

	} 
	catch (Exception e) {
		e.printStackTrace();
	}

    }
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -