第三步 实现信息共享:在socket上的实时交流
网络的伟大之一也是信息共享,server可以主动向所有client广播消息,同时client也可以向其它client发布消息。下面看看如何开发一个可以实时传递消息的程序。
设计原理:
服务器端接受客户端的连接请求,同时启动一个线程处理这个连接,线程不停的读取客户端输入,然后把输入加入队列中,等候处理。在线程启动的同时将线程加入队列中,以便在需要的时候定位和取出。
{源码}
import java.io.*;
import java.net.*;
import java.util.*;
import java.lang.*;
public class server extends serversocket
{
private static arraylist user_list = new arraylist();
private static arraylist threader = new arraylist();
private static linkedlist message_array = new linkedlist();
private static int thread_counter = 0;
private static boolean isclear = true;
protected static final int server_port = 10000;
protected fileoutputstream log_file = new fileoutputstream("d:/connect.log", true);
public server() throws filenotfoundexception, ioexception
{
super(server_port);
new broadcast();
//append connection log
calendar now = calendar.getinstance();
string str = "[" + now.gettime().tostring() + "] accepted a connection\015\012";
byte[] tmp = str.getbytes();
log_file.write(tmp);
try
{
while (true)
{
socket socket = accept();
new createserverthread(socket);
}
}
finally
{
close();
}
}
public static void main(string[] args) throws ioexception
{
new server();
}
//— broadcast
class broadcast extends thread
{
public broadcast()
{
start();
}
public void run()
{
while (true)
{
if (!isclear)
{
string tmp = (string)message_array.getfirst();
for (int i = 0; i < threader.size(); i++)
{
createserverthread client = (createserverthread)threader.get(i);
client.sendmessage(tmp);
}
message_array.removefirst();
isclear = message_array.size() > 0 ? false : true;
}
}
}
}
//— createserverthread
class createserverthread extends thread
{
private socket client;
private bufferedreader in;
private printwriter out;
private string username;
public createserverthread(socket s) throws ioexception
{
client = s;
in = new bufferedreader(new inputstreamreader(client.getinputstream()));
out = new printwriter(client.getoutputstream(), true);
out.println("— welcome to this chatroom —");
out.println("input your nickname:");
start();
}
public void sendmessage(string msg)
{
out.println(msg);
}
public void run()
{
try
{
int flag = 0;
thread_counter++;
string line = in.readline();
while (!line.equals("bye"))
{
if (line.equals("l"))
{
out.println(listonlineusers());
line = in.readline();
continue;
}
if (flag++ == 0)
{
username = line;
user_list.add(username);
out.println(listonlineusers());
threader.add(this);
pushmessage("[< " + username + " come on in >]");
}
else
{
pushmessage("<" + username + ">" + line);
}
line = in.readline();
}
out.println("— see you, bye! —");
client.close();
}
catch (ioexception e)
{}
finally
{
try
{
client.close();
}
catch (ioexception e)
{}
thread_counter–;
threader.remove(this);
user_list.remove(username);
pushmessage("[< " + username + " left>]");
}
}
private string listonlineusers()
{
string s ="-+- online list -+-\015\012";
for (int i = 0; i < user_list.size(); i++)
{
s += "[" + user_list.get(i) + "]\015\012";
}
s += "-+———————+-";
return s;
}
private void pushmessage(string msg)
{
message_array.addlast(msg);
isclear = false;
}
}
}
这就是程序运行后,多用户登陆并且输入信息后的屏幕。实现了信息的实时广播。用户输入"l"就可以列出在线人员表。
