程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> JAVA編程 >> JAVA綜合教程 >> Socket通信 簡單實現私聊、群聊(dos命令下),socketdos

Socket通信 簡單實現私聊、群聊(dos命令下),socketdos

編輯:JAVA綜合教程

Socket通信 簡單實現私聊、群聊(dos命令下),socketdos


很久以前的一個Demo,這裡服務器只做轉發功能,根據ID地址和端口號來標識身份,群聊和私聊只是簡單實現,

服務器代碼如下:

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

public class Server extends Thread 
{
    private static Vector<Socket> vecClient = new Vector<Socket>(); 
    private PrintWriter out;
    private BufferedReader in;
    private Socket clientsocket;

    public static void main(String[] args) throws IOException {
        ServerSocket server = new ServerSocket(2014); // 創建
        System.out.println("啟動服務器! ");
        Socket sock;

        while (true) {
            sock = server.accept(); // 等待客戶請求
            Server ser = new Server(sock); 
            ser.start(); // 啟動
        }
    }

    public Server(Socket socket) {
        this.clientsocket = socket;
        vecClient.addElement(socket); // 增加客戶線程到數組
        try {
            // 獲取服務端傳來的字節流好,存到緩沖區
            in = new BufferedReader(new InputStreamReader(
                    socket.getInputStream()));
            // printwriter,文本輸出流打印對象的格式化表示形式,只有調用println等,自動刷新即true,強行把緩沖區的數據輸出。
            out = new PrintWriter(new OutputStreamWriter(
                    socket.getOutputStream()), true);
            // input、OutputStreamWriter 是字符流通向字節流的橋梁
        } catch (IOException e) {
        }
    }

    public void run()             
    {        
        try
        { 
            Newclient();          // 向新客戶發出歡迎信息,通知所有在線客戶有新客戶連接了
            while(true)          // 處理與客戶的交流
            {
                String msg=in.readLine();    //數據讀取      
                
                if(msg.equals("bye")|| msg.equals("拜拜"))//當輸入拜拜或bye時候退出
                {
                    Xiaxian();             
                    in.close();          // 關閉輸入流
                    clientsocket.close(); // 關閉socket
                    break;
                }
                else if(msg.indexOf("@")==0&&msg.indexOf(" ")>0){
                    int end=msg.indexOf(" ");
                    String findAddr=msg.substring(1,end);
                    if(vecClient.isEmpty() == false) //判斷為空
                        {
                        for(int i=0;i<vecClient.size();i++)
                        {
                            Socket socket = vecClient.get(i);
                            String addr = socket.getInetAddress().toString().replace("/", "") + ":"
                                    + socket.getPort();
                            if(findAddr.equals(addr)){
                                String addr2 = clientsocket.getInetAddress().toString().replace("/", "") + ":"
                                        + clientsocket.getPort();
                                //elementAt返回指定索引處的組件,而get返回列表中指定位置處的元素
                                PrintWriter pw = new PrintWriter(new OutputStreamWriter(vecClient.get(i).getOutputStream()),true); 
                                pw.println("大神"+addr2+" 對你 說: "+msg.substring(end));
                            }
                        }
                        }
                }
                // 否則將接收到的信息向所有在線客戶發出去
                else
                {
                    if(vecClient.isEmpty() == false) 
                        for(int i=0;i<vecClient.size();i++)
                        {
                            //elementAt返回指定索引處的組件,而get返回列表中指定位置處的元素
                            PrintWriter pw = new PrintWriter(new OutputStreamWriter(vecClient.get(i).getOutputStream()),true); 
                            pw.println("大神"+clientsocket.getInetAddress().toString()+":"+clientsocket.getPort()+" 說: "+msg);
                        }
                }
            }
        }
        catch(IOException e)
        { }
    }

    public void Newclient() throws IOException // 新來的,用此函數
    {
        String addr = clientsocket.getInetAddress().toString() + ":"
                + clientsocket.getPort();
        out.println("歡迎:" + addr+"加入! ");
        try {
            if (vecClient.isEmpty() == false)
                for (int i = 0; i < vecClient.size(); i++)
                {
                    Socket socket = vecClient.get(i);
                    PrintWriter pw = new PrintWriter(new OutputStreamWriter(
                            socket.getOutputStream()), true);
                    String addr2 = socket.getInetAddress().toString() + ":"
                            + socket.getPort();
                    if (addr.equals(addr2)) {
                        pw.println("歡迎加入聊天,私聊請用@ip:port 內容");
                    } else {
                        pw.println("新成員:"
                                + clientsocket.getInetAddress().toString()
                                + ":" + clientsocket.getPort() + "  嗨起來吧!");
                    }
                }
        } catch (IOException e) {
        }
    }

    public void Xiaxian() throws IOException // 下線方法
    {
        out.println("再見,連接關閉!");
        if (vecClient.isEmpty() == false)
            for (int i = 0; i < vecClient.size(); i++) {
                PrintWriter pw = new PrintWriter(new OutputStreamWriter(vecClient
                        .get(i).getOutputStream()), true);
                pw.println("--" + clientsocket.getInetAddress().toString()
                        + ":" + clientsocket.getPort() + " 已經下線");
            }
        vecClient.remove(clientsocket); 
    }
}
View Code

客服端,可在本地命令運行多個測試,私聊格式:@ip:port(這裡必須有空格)內容,原理如下:

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

class Client
{   
    public static void main(String[] args)
    {
        try
          {    
                Socket socket=new Socket("localhost",2014);                                
                ClientSend send=new ClientSend(socket);            // 創建發送線程
                ClientReceive receive=new ClientReceive(socket); // 創建接收線程
                send.start();                                       // 啟動發送線程
                receive.start();                                  // 啟動接收線程
          }
        catch(Exception e) 
          {
            System.out.println("服務器沒有開啟呢!");
            e.printStackTrace();
          }
                   
    }
}

class ClientSend extends Thread
{
    private Socket socket;
    private PrintWriter out;
    
    public ClientSend(Socket socket)
    {
        this.socket=socket;
        try
        {
            out=new PrintWriter(new OutputStreamWriter(socket.getOutputStream()),true);
        //返回一個服務器與客戶端的輸出流,true強行把緩沖區的數據輸出
        }
        catch(IOException e)
        {
            e.printStackTrace();
        }
    }
    
    public void run()  // 發送信息到服務器
    {
        String msg;
        Scanner input=new Scanner(System.in);//輸入
        msg = input.nextLine();                //nextLine方法返回的是回車之前的所有字符
        while(true)
        {
            //用equalsIgnoreCase可忽略大小寫
            if(msg.equals("bye") || msg.equals("拜拜"))
            {
                out.println(msg);
                break;
            }                        
            out.println(msg);
            msg = input.nextLine();            
        }
    }
}

class ClientReceive extends Thread            //接收
{
    private Socket socket;
    private BufferedReader in;
    
    public ClientReceive(Socket socket)
    {
        this.socket= socket;
        try
        {
            in=new BufferedReader(new InputStreamReader(socket.getInputStream()));
        }
        catch(IOException e)
        {
            e.printStackTrace();
        }
    }
    
    public void run() // 接收服務器發來的信息
    {        
        try
        {
            String msg=in.readLine();
            while(msg.equals("bye") == false)
            {
                System.out.println(msg);
                msg=in.readLine();
            }
            in.close();
            socket.close();
        }
        catch(IOException e)
        {
            e.printStackTrace();
        }        
    }
}
View Code

 

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved