比如,有10000个用户在聊天室内,服务端可以指定100个人先将消息发给他们,
然后,这100个人,每人再发99个人,就完成广播的扩散了。
但是,服务端还要对本次广播的扩散情况进行辅助管理才行。
客户端之间的广播传递,可通过UDP/TCP的“打孔技术”进行实现
CS模式的QQ这是服务器:ChatServer.javaimport java.net.*import java.io.*
public class ChatServer
{
final static int thePort=8189
ServerSocket theServer
ChatHandler[] chatters
int numbers=0
public static void main(String args[])
{
ChatServer app=new ChatServer()
app.run()
}
public ChatServer()
{
try
{
theServer=new ServerSocket(thePort)
chatters=new ChatHandler[10]
}
catch(IOException io){}
}
public void run()
{
try
{
System.out.println("服务器已经建立!")
while(numbers<10)
{
Socket theSocket=theServer.accept()
ChatHandler chatHandler=new ChatHandler(theSocket,this)
chatters[numbers]=chatHandler
numbers++
}
}catch(IOException io){}
}
public synchronized void removeConnectionList(ChatHandler c)
{
int index=0
for(int i=0i<=numbers-1i++)
if(chatters[i]==c)index=i
for(int i=indexi<numbers-1i++)
chatters[i]=chatters[i+1]
chatters[numbers-1]=null
numbers--
}
public synchronized String returnUsernameList()
{
String line=""
for(int i=0i<=numbers-1i++)
line=line+chatters[i].user+":"
return line
}
public void broadcastMessage(String line)
{
System.out.println("发布信息:"+line)
for(int i=0i<=numbers-1i++)
chatters[i].sendMessage(line)
}
}====================================================这是客户端:ChatClient.javaimport java.awt.*
import java.awt.event.*
import javax.swing.*
import java.net.*
import java.io.*
public class ChatClient extends Thread implements ActionListener
{
JTextField messageField,IDField,ipField,portField
JTextArea message,users
JButton connect,disconnect
String user=""
String userList[]=new String[10]
Socket theSocket
BufferedReader in
PrintWriter out
boolean connected=false
Thread thread
public static void main(String args[])
{
JFrame frame=new JFrame("聊天室")
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE)
ChatClient cc=new ChatClient()
JPanel content=cc.createComponents()
frame.getContentPane().add(content)
frame.setSize(550,310)
frame.setVisible(true)
}
public JPanel createComponents()
{
JPanel pane=new JPanel(new BorderLayout())
message=new JTextArea(10,35)
message.setEditable(false)
JPanel paneMsg=new JPanel()
paneMsg.setBorder(BorderFactory.createTitledBorder("聊天内容"))
paneMsg.add(message)
users=new JTextArea(10,10)
JPanel listPanel=new JPanel()
listPanel.setBorder(BorderFactory.createTitledBorder("在线用户:"))
listPanel.add(users)
messageField=new JTextField(50)
IDField=new JTextField(5)
ipField=new JTextField("LocalHost")
portField=new JTextField("8189")
connect=new JButton("连 接")
disconnect=new JButton("断 开")
disconnect.setEnabled(false)
JPanel buttonPanel=new JPanel()
buttonPanel.add(new Label("服务器IP:"))
buttonPanel.add(ipField)
buttonPanel.add(new Label("端口:"))buttonPanel.add(portField)
buttonPanel.add(new Label("用户名:"))
buttonPanel.add(IDField)
buttonPanel.add(connect)
buttonPanel.add(disconnect)
pane.add(messageField,"South")
pane.add(buttonPanel,"North")
pane.add(paneMsg,"Center")
pane.add(listPanel,"West")
connect.addActionListener(this)
disconnect.addActionListener(this)
messageField.addActionListener(this)
IDField.addActionListener(this)
ipField.addActionListener(this)
return pane
}
public void actionPerformed(ActionEvent e)
{
if(e.getSource()==connect){
user=IDField.getText()
String ip=ipField.getText()
int port =Integer.parseInt(portField.getText())
if(!user.equals("")&&connectToServer(ip,port,user))
{
disconnect.setEnabled(true)
connect.setEnabled(false)
}
}
if(e.getSource()==disconnect)disconnectFromServer()
if(e.getSource()==messageField)
if(theSocket!=null)
{
out.println("MESSAGE:"+messageField.getText())
messageField.setText("")
}
}
public void disconnectFromServer()
{
if(theSocket!=null)
{
try
{
connected=false
out.println("LEAVE:"+user)
disconnect.setEnabled(false)
connect.setEnabled(true)
thread=null
theSocket.close()
}catch(IOException io){}
theSocket=null
message.setText("")
users.setText("")
}
}
public boolean connectToServer(String ip,int port,String ID)
{
if(theSocket!=null)
return false
try
{
theSocket=new Socket(ip,port)
in=new BufferedReader(new InputStreamReader(theSocket.getInputStream()))
out=new PrintWriter(new OutputStreamWriter(theSocket.getOutputStream()),true)
out.println("USER:"+user)
message.setText("")
connected=true
thread=new Thread(this)
thread.start()
}catch(Exception e){return false}
return true
}
public void extractMessage(String line)
{
System.out.println(line)
Message messageline
messageline=new Message(line)
if(messageline.isValid())
{
if(messageline.getType().equals("JOIN"))
{
user=messageline.getBody()
message.append(user+"进入了聊天室\n")
}
else if(messageline.getType().equals("LIST"))
updateList(messageline.getBody())
else if(messageline.getType().equals("MESSAGE"))
message.append(messageline.getBody()+"\n")
else if(messageline.getType().equals("REMOVE"))
message.append(messageline.getBody()+"离开了聊天室\n")
}
else
message.append("出现问题:"+line+"\n")
}
public void updateList(String line)
{
users.setText("")
String str=line
for(int i=0i<10i++)
userList[i]=""
int index=str.indexOf(":")
int a=0
while(index!=-1){
userList[a]=str.substring(0,index)
str=str.substring(index+1)
a++
index=str.indexOf(":")
}
for(int i=0i<10i++)
users.append(userList[i]+"\n")
}
public void run(){
try{
String line=""
while(connected &&line!=null){
line=in.readLine()
if(line!=null) extractMessage(line)
}
}catch(IOException e){}
}
} =======================================================import java.net.*
import java.io.*
class ChatHandler extends Thread{
Socket theSocket
BufferedReader in
PrintWriter out
int thePort
ChatServer parent
String user=""
boolean disconnect=false
public ChatHandler(Socket socket,ChatServer parent){
try{
theSocket=socket
this.parent=parent
in=new BufferedReader(new InputStreamReader(theSocket.getInputStream()))
out=new PrintWriter(new OutputStreamWriter(theSocket.getOutputStream()),true)
thePort=theSocket.getPort()
start()
}catch(IOException io){}
}
public void sendMessage(String line){
out.println(line)
}
public void setupUserName(String setname){
user=setname
//System.out.print(user+"参加")
parent.broadcastMessage("JOIN:"+user)
}
public void extractMessage(String line){
Message messageline
messageline = new Message(line)
if(messageline.isValid()){
if(messageline.getType().equals("USER")){
setupUserName(messageline.getBody())
parent.broadcastMessage("LIST:"+parent.returnUsernameList())
}
else if(messageline.getType().equals("MESSAGE")){
parent.broadcastMessage("MESSAGE:"+user+"说: "+messageline.getBody())
}
else if(messageline.getType().equals("LEAVE")){
String c=disconnectClient()
parent.broadcastMessage("REMOVE:"+c)
parent.broadcastMessage("LIST:"+parent.returnUsernameList())
}
}
else
sendMessage("命令不存在!")
}
public String disconnectClient(){
try{
in.close()
out.close()
theSocket.close()
parent.removeConnectionList(this)
disconnect=true
}catch(Exception ex){}
return user
}
public void run(){
String line,name
boolean valid=false
try{
while((line=in.readLine())!=null){
System.out.println("收到:"+line)
extractMessage(line)
}
}catch(IOException io){}
}
}
=========================================================
Message.javapublic class Message{
private String type
private String body
private boolean valid
public Message(String messageLine){
valid=false
type=body=null
int pos=messageLine.indexOf(":")
if(pos>=0){
type=messageLine.substring(0,pos).toUpperCase()
body=messageLine.substring(pos+1)
valid=true
}
}
public Message(String type,String body){
valid=true
this.type=type
this.body=body
}
public String getType(){
return type
}
public String getBody(){
return body
}
public boolean isValid(){
return valid
}
} ==================================================共有4个文件,先运行服务段端。。。 这是我以前学的时候写过的!希望能帮的上你
欢迎分享,转载请注明来源:夏雨云
评论列表(0条)