【Java Socket】【Flex Socket】【Java 多线程】实现基本聊天功能demo

java服务端代码:两个类【ChatServer.java 】【ChatThread.java】

ChatServer作用是监听客户端连接请求,如果有新socket连接,生成一个新的线程以应对本次socket连接。

ChatThread作用是:与某一客户端socket绑定,监听客户端发送的信息,然后将收到的信息“广播”到其他所有客户端。

【原创】

package sockettest;



import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.LinkedList;
import java.util.List;

public class ChatServer {
//公共聊天室
    public static void main(String[] args) throws IOException {
        ServerSocket ss=new ServerSocket(6666);
        
        List<Socket> socketList=new LinkedList<Socket>();
        
        while(true){
            Socket socket=ss.accept();
            socketList.add(socket);
            
            Thread t=new Thread(new ChatThread(socket,socketList));
            t.start();    
        }
    }
}
package sockettest;

import java.io.*;
import java.net.*;
import java.util.List;

public class ChatThread implements Runnable{

    private static String xml = "<?xml version=\"1.0\"?><cross-domain-policy><site-control permitted-cross-domain-policies=\"all\"/><allow-access-from domain=\"*\" to-ports=\"*\"/></cross-domain-policy>\0";
    
    
    private List<Socket> socketList;
    private Socket socket;
    private BufferedReader bufferedReader;
    
    public ChatThread(Socket socket,List<Socket> socketList){
        this.socket=socket;
        this.socketList=socketList;
    }
    
    private void  preRun(){
        PrintWriter pw=this.getSocketPrintWriter(socket);
        pw.println(xml);
        pw.flush();
        
        InputStreamReader r=null;
        try {
            r = new InputStreamReader(this.socket.getInputStream(),"UTF-8");
            this.bufferedReader=new BufferedReader(r);    
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
    
    private PrintWriter getSocketPrintWriter(Socket socket){
        OutputStream os=null;
        try {
            os = socket.getOutputStream();
        } catch (IOException e) {
            e.printStackTrace();
        }
        
        
        OutputStreamWriter osw=new OutputStreamWriter(os);
        BufferedWriter bw=new BufferedWriter(osw);
        return new PrintWriter(bw, true);
    }
    private void broadcast(String msg){
        for(Socket s:socketList){
            PrintWriter pw=this.getSocketPrintWriter(s);
            pw.println(msg);
        }
    }
    public void run() {
        String msg="";
        this.preRun();
        while(true){
            try {
                msg="from client "+this.bufferedReader.readLine();
                this.broadcast(msg);
            } catch (IOException e) {
                try {
                    this.bufferedReader.close();
                    this.socket.close();
                    this.socketList.remove(this.socket);
                    this.broadcast("somebody exist....people size :"
                                  +socketList.size());
                } catch (IOException e1) {
                    e1.printStackTrace();
                }
                e.printStackTrace();
                return ;
            }
        }
    }
}


Flex客户端代码:【ChatClientDemo.mxml】【LoginWnd.mxml】【GlobalMasage.as

Flsha Builder 4.5

ChatClientDemo.mxml 聊天注界面,实现socket通信

<?xml version="1.0" encoding="utf-8"?>
<s:Application xmlns:fx="http://ns.adobe.com/mxml/2009" 
               xmlns:s="library://ns.adobe.com/flex/spark" 
               xmlns:mx="library://ns.adobe.com/flex/mx" minWidth="955" minHeight="600"  creationComplete="application1_creationCompleteHandler(event)">
    <fx:Style source="ChatClientDemo.css"/>
    <fx:Declarations>
        <!-- 将非可视元素(例如服务、值对象)放在此处 -->
        
    </fx:Declarations>
    <fx:Script>
        <![CDATA[
            import mx.events.FlexEvent;
            import mx.managers.PopUpManager;
            import mx.messaging.channels.StreamingAMFChannel;
            
            
            private var loginWnd:LoginWnd=new LoginWnd();
            private var socket:Socket=new Socket();
            protected function application1_creationCompleteHandler(event:FlexEvent):void
            {
                PopUpManager.addPopUp(loginWnd,this,true);
                PopUpManager.centerPopUp(loginWnd); 
            }
            
            protected function btnConn_clickHandler(event:MouseEvent):void
            {
                socket.connect(GlobalMasage.SERVER_HOST,GlobalMasage.SERVER_PORT);
                socket.addEventListener(Event.CONNECT,event_connHandler);
                socket.addEventListener(ProgressEvent.SOCKET_DATA,event_receiveFromServerHandler);
                socket.addEventListener(Event.CLOSE,event_closeHandler);
            }
            
            protected function btnSend_clickHandler(event:MouseEvent):void
            {
                var msg:ByteArray=new ByteArray();
                msg.writeUTFBytes(GlobalMasage.loginName+":"+txtInput.text+"\n");
                socket.writeBytes(msg);
                socket.flush();
                this.txtInput.text="";
            }
            private function event_closeHandler(event:Event):void{
                
            }

            private function event_connHandler(event:Event):void{
                this.txtContainer.text+="-----------服务器链接成功---------\n";
            }
            private function event_receiveFromServerHandler(event:ProgressEvent):void
            {
                var msg:String=null;
                msg=socket.readMultiByte(socket.bytesAvailable,"utf8");
                this.txtContainer.text+=msg+"\n";
            }
    
            
            protected function btnClearScreen_clickHandler(event:MouseEvent):void
            {
                this.txtContainer.text="";
                
            }
            
        ]]>
    </fx:Script>
    <s:TextArea id="txtContainer" x="64" y="16" width="480" height="277"/>
    <s:TextInput id="txtInput" x="64" y="326" width="480"/>
    <s:Button id="btnConn" x="552" y="16" label="连接" click="btnConn_clickHandler(event)"/>
    <s:Button id="btnClearScreen" x="552" y="62" label="清屏"
              click="btnClearScreen_clickHandler(event)"/>
    <s:Button x="552" y="118" label="断开"/>
    <s:Button id="btnSend" x="552" y="327" label="发送" click="btnSend_clickHandler(event)"/>
</s:Application>

LoginWnd.mxml 用于用户登录,输入一个用户名,无需注册

<?xml version="1.0" encoding="utf-8"?>
<s:Group xmlns:fx="http://ns.adobe.com/mxml/2009" 
         xmlns:s="library://ns.adobe.com/flex/spark" 
         xmlns:mx="library://ns.adobe.com/flex/mx" width="400" height="300">

    <fx:Script>
        <![CDATA[
            import mx.managers.PopUpManager;
            
            protected function btnLogin_clickHandler(event:MouseEvent):void
            {
                // TODO Auto-generated method stub
                GlobalMasage.loginName=txtLoginName.text;
                PopUpManager.removePopUp(this);
            }
        ]]>
    </fx:Script>
    
    <fx:Declarations>
        <!-- 将非可视元素(例如服务、值对象)放在此处 -->
    </fx:Declarations>
    

    <s:Panel x="0" y="0" width="400" height="300">
        <s:Label x="81" y="99" width="48" height="19" fontSize="15" text="名字"/>
        <s:TextInput id="txtLoginName" x="145" y="95"/>
        <s:Button id="btnLogin" x="145" y="154" label="登录" click="btnLogin_clickHandler(event)"/>
    </s:Panel>
</s:Group>

 l

GlobalMasage.as :只是用来存储全局变量
package
{
    [Bindable]
    public class GlobalMasage
    {
        public function GlobalMasage()
        {
        }
        public static var SERVER_HOST:String="127.0.0.1";
        public static var SERVER_PORT:Number=6666;
        public static var loginName:String;
    }
}








 
 
原文地址:https://www.cnblogs.com/lhp2012/p/2447935.html