java网络编程、多线程实现多人即时聊天、Mina即时通讯框架

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/xzpdskll/article/details/82285927

一、socket编程
1、建立服务端程序

ServerSocket serverSocket = new ServerSocket(6666);
System.out.println("服务器已经启动,等待客户端连接请求。。。");
/**调用accept方法,等待连接,将会阻塞程序执行*/
Socket accept = serverSocket.accept();
System.out.println("客户端已连接:"+accept.getRemoteSocketAddress());
System.out.println("服务端接收到数据:");

BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(accept.getInputStream()));
String inputString = bufferedReader.readLine();
System.out.println(inputString);

System.out.println("服务端返回数据到客户端:");
PrintStream printStream = new PrintStream(accept.getOutputStream());
printStream.println("echo:"+inputString);
printStream.flush();

printStream.close();
bufferedReader.close();

2、建立客户端程序

Socket socket = new Socket("127.0.0.1",6666);
System.out.println("客户端已经连接服务端,即将写入数据:hello,I am sunkeliang");
PrintStream printStream = new PrintStream(socket.getOutputStream());
printStream.println("hello,I am sunkeliang");
printStream.flush();

System.out.println("接收服务端返回的数据:");
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(socket.getInputStream()));
String inputString = bufferedReader.readLine();
System.out.println(inputString);

bufferedReader.close();
printStream.close();

二、多人即时聊天
1.建立服务端程序(启动一个即可),多人即时聊天服务端

package com.imp4m.network_programming.communicate;


import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.Vector;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

/**
 * 即时聊天服务端
 */
public class MultChatServer {


    public static void main(String args[]){
        Vector<MultTransferTask> taskVector = new Vector<>();
        ExecutorService executorService = Executors.newFixedThreadPool(3);
        try {
            ServerSocket serverSocket = new ServerSocket(8888);
            System.out.println("服务器启动成功,等待客户端的连接...");
            while (true){
                Socket socket = serverSocket.accept();
                executorService.execute(new MultTransferTask(socket,taskVector));
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

/**
 * 服务器中转服务
 */
class MultTransferTask implements Runnable{
    private String name;
    private Socket socket;
    private ObjectInputStream objectInputStream;
    private ObjectOutputStream objectOutputStream;
    private Vector<MultTransferTask> taskVector;


    public MultTransferTask(Socket socket,Vector<MultTransferTask> taskVector) {
        this.socket = socket;
        this.taskVector = taskVector;
        taskVector.add(this);
    }

    @Override
    public void run() {
        System.out.println("客户端:"+socket.getInetAddress().getHostName()+"已连接");
        try {
            objectInputStream = new ObjectInputStream(socket.getInputStream());
            objectOutputStream = new ObjectOutputStream(socket.getOutputStream());
            while (true){
               Message message = (Message) objectInputStream.readObject();
               int type = message.getType();
               switch (type){
                   case MessageType.SEND:
                       String to = message.getTo();
                       int size = taskVector.size();
                       MultTransferTask multTransferTask;
                       boolean isExist = false;
                       for (int i = 0; i < size; i++) {
                           multTransferTask = taskVector.get(i);
                           if(to.equals(multTransferTask.name) && multTransferTask!=this){
                               multTransferTask.objectOutputStream.writeObject(message);
                               isExist = true;
                               break;
                           }
                       }
                       if(!isExist){
                           message.setFrom("系统通知");
                           message.setInfo("["+to+"]不在线");
                           objectOutputStream.writeObject(message);
                       }
                       break;
                   case MessageType.LOGIN:
                       name = message.getFrom();
                       message.setInfo("欢迎你");
                       objectOutputStream.writeObject(message);

                       /**通知所有在线用户上线*/
                       int size1 = taskVector.size();
                       MultTransferTask multTransferTask1;
                       for (int i = 0; i < size1; i++) {
                           multTransferTask1 = taskVector.get(i);
                           if(multTransferTask1!=this){
                               message.setInfo("我上线了");
                               message.setType(MessageType.SEND);
                               multTransferTask1.objectOutputStream.writeObject(message);
                           }
                       }
                       break;
               }
            }
        } catch (IOException | ClassNotFoundException e) {
            System.out.println("客户端["+name+"]已经断开连接");
            taskVector.remove(this);
            /**通知所有在线用户上线*/
            int size1 = taskVector.size();
            Message message = new Message();
            MultTransferTask multTransferTask1;
            for (int i = 0; i < size1; i++) {
                multTransferTask1 = taskVector.get(i);
                message.setFrom(this.name);
                message.setType(MessageType.SEND);
                message.setInfo("我下线了");
                try {
                    multTransferTask1.objectOutputStream.writeObject(message);
                } catch (IOException e1) {
                    e1.printStackTrace();
                }
            }
        }finally {
            if(objectInputStream!=null){
                try {
                    objectInputStream.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }

            if(objectOutputStream!=null){
                try {
                    objectOutputStream.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }
}

2.多人即时聊天客户端(可启动多个,实现多个客户端之间通讯)

package com.imp4m.network_programming.communicate;

import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.net.Socket;
import java.util.Scanner;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

/**
 * 即时聊天客户端
 */
public class MultChatClient {

    public static void main(String args[]) {
        Scanner scanner = new Scanner(System.in);
        ExecutorService executorService = Executors.newSingleThreadExecutor();
        try {
            Socket socket = new Socket("localhost",8888);
            ObjectOutputStream oos = new ObjectOutputStream(socket.getOutputStream());
            ObjectInputStream ois = new ObjectInputStream(socket.getInputStream());

            /**登录*/
            System.out.println("请输入用户名进行登录:");
            String inputInfo = scanner.nextLine();
            Message message = new Message(inputInfo,null,null,MessageType.LOGIN);
            oos.writeObject(message);

            message = (Message)ois.readObject();
            System.out.println("登录成功,"+message.getInfo()+":"+message.getFrom());

            /**启动接收消息任务*/
            executorService.execute(new ReadMessageTask(ois));

            while (true){
                message = new Message();
                System.out.println("请输入接收者:");
                String to = scanner.nextLine();
                message.setTo(to);
                message.setFrom(inputInfo);
                message.setType(MessageType.SEND);
                System.out.println("请输入发送内容:");
                message.setInfo(scanner.nextLine());
                oos.writeObject(message);
            }
        } catch (IOException |ClassNotFoundException e) {
            e.printStackTrace();
        }
    }
}


class ReadMessageTask implements Runnable {
    private ObjectInputStream in;

    public ReadMessageTask(ObjectInputStream in) {
        this.in = in;
    }

    @Override
    public void run() {
        try {
            while (true){
                Message msg = ((Message) in.readObject());
                if(msg.getType() == MessageType.SEND){
                    System.out.println("["+msg.getFrom()+"]对我说:"+msg.getInfo());
                }
            }
        } catch (IOException | ClassNotFoundException e) {
            e.printStackTrace();
        }finally {
            if(in!=null){
                try {
                    in.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }
}

3、消息报文类

package com.imp4m.network_programming.communicate;


import java.io.Serializable;

/**
 * 消息报文类
 */
public class Message implements Serializable{

    private String from;

    private String to;

    private String info;

    private int type;

    public Message() {

    }

    public Message(String from, String to, String info, int type) {
        this.from = from;
        this.to = to;
        this.info = info;
        this.type = type;
    }

    public String getFrom() {
        return from;
    }

    public void setFrom(String from) {
        this.from = from;
    }

    public String getTo() {
        return to;
    }

    public void setTo(String to) {
        this.to = to;
    }

    public String getInfo() {
        return info;
    }

    public void setInfo(String info) {
        this.info = info;
    }

    public int getType() {
        return type;
    }

    public void setType(int type) {
        this.type = type;
    }
}

4、消息类型

package com.imp4m.network_programming.communicate;


/**
 * 消息类型
 */
public final class MessageType {
    public static final int LOGIN = 0x1;
    public static final int SEND = 0x2;
}

三、UDP方式通讯
1.客户端程序

package com.imp4m.network_programming.udp;

import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.SocketException;

public class UDPClient {

    public static void main(String[] args) {
        DatagramSocket socket = null;
        try {
            socket = new DatagramSocket(5000);
            byte bytes1[] = new byte[1024];
            DatagramPacket datagramPacket1 = new DatagramPacket(bytes1,0,bytes1.length);
            socket.receive(datagramPacket1);
            byte[] data = datagramPacket1.getData();
            System.out.println(new String(data,"utf-8"));
        } catch (SocketException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }

    }
}

2、服务端程序

package com.imp4m.network_programming.udp;

import java.io.IOException;
import java.net.*;

public class UDPServer {

    public static void main(String[] args) {
        String s = "my name is sunkeliang,i love menyue";
        byte bytes[] = s.getBytes();

        try {
            DatagramPacket datagramPacket = new DatagramPacket(bytes,0,bytes.length, InetAddress.getByName("127.0.0.1"),5000);
            DatagramSocket socket = new DatagramSocket(6000);
            socket.send(datagramPacket);
            byte bytes1[] = new byte[1024];
            DatagramPacket datagramPacket1 = new DatagramPacket(bytes1,0,bytes1.length);
            socket.receive(datagramPacket1);

            byte[] data = datagramPacket1.getData();
            System.out.println(new String(data,"utf-8"));
        } catch (UnknownHostException e) {
            e.printStackTrace();
        } catch (SocketException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

四、URL方式获取网络资源

package com.imp4m.network_programming.url;

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLConnection;

public class UrlDemo {

    public static void main(String[] args) {
        BufferedInputStream bufferedInputStream = null;
        BufferedOutputStream bufferedOutputStream = null;
        try {
            URL url = new URL("http://img.zcool.cn/community/0117e2571b8b246ac72538120dd8a4.jpg@1280w_1l_2o_100sh.jpg");
            URLConnection urlConnection = url.openConnection();
            bufferedInputStream = new BufferedInputStream(urlConnection.getInputStream());
            bufferedOutputStream = new BufferedOutputStream(new FileOutputStream("D://1.jpg"));
            byte b[] = new byte[1024];
            while (bufferedInputStream.read(b)!=-1){
                bufferedOutputStream.write(b);
            }
        } catch (MalformedURLException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }finally {
            if(bufferedInputStream!=null){
                try {
                    bufferedInputStream.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }

            if(bufferedOutputStream!=null){
                try {
                    bufferedOutputStream.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }
}

五、Mina即时通讯框架
1、建立Mina通讯服务端程序

package com.imp4m.nio_io.mina;


import org.apache.mina.core.filterchain.DefaultIoFilterChainBuilder;
import org.apache.mina.filter.codec.ProtocolCodecFilter;
import org.apache.mina.filter.codec.serialization.ObjectSerializationCodecFactory;
import org.apache.mina.transport.socket.SocketAcceptor;
import org.apache.mina.transport.socket.nio.NioSocketAcceptor;

import java.io.IOException;
import java.net.InetSocketAddress;

/**
 * MinaServer端
 */
public class MinaServer {

    public static void main(String[] args) {

        /**创建一个非阻塞的Server端Socket*/
        SocketAcceptor acceptor = new NioSocketAcceptor();

        /**获取这个*/
        DefaultIoFilterChainBuilder filterChain = acceptor.getFilterChain();

        /**创建一个过滤器,一行一行的读取,(\r\n)*/
        filterChain.addLast("default_Mina_Filter",new ProtocolCodecFilter(new ObjectSerializationCodecFactory()));

        /**添加一个自定义个服务端处理器*/
        acceptor.setHandler(new DefaultServerMinaHandler());

        /**绑定一个端口*/
        int port = 9999;
        try {
            acceptor.bind(new InetSocketAddress(port));

        } catch (IOException e) {
            e.printStackTrace();
        }
        System.out.println("Mina is running,listening to:"+port);
    }
}

2、建立服务端消息处理器

package com.imp4m.nio_io.mina;

import com.imp4m.nio_io.mina.domian.Message;
import org.apache.mina.core.service.IoHandlerAdapter;
import org.apache.mina.core.session.IoSession;

public class DefaultServerMinaHandler extends IoHandlerAdapter {

    @Override
    public void sessionCreated(IoSession session) throws Exception {
        super.sessionCreated(session);
        System.out.println("客户端["+session.getRemoteAddress()+"]:session已创建");
    }

    @Override
    public void sessionOpened(IoSession session) throws Exception {
        super.sessionOpened(session);
        System.out.println("客户端["+session.getRemoteAddress()+"]:已连接");
    }

    @Override
    public void sessionClosed(IoSession session) throws Exception {
        super.sessionClosed(session);
        System.out.println("客户端["+session.getRemoteAddress()+"]:已关闭");
    }

    @Override
    public void messageReceived(IoSession session, Object message) throws Exception {
        super.messageReceived(session,message);
        Message mes = (Message) message;
        System.out.println("收到客户端发送的消息:"+mes.getId()+"---"+mes.getName());
        mes.setName("echo:"+mes.getName());
        session.write(mes);
    }
}

3.建立mina通讯客服端程序

package com.imp4m.nio_io.mina;

import com.imp4m.nio_io.mina.domian.Message;
import org.apache.mina.core.filterchain.DefaultIoFilterChainBuilder;
import org.apache.mina.core.future.ConnectFuture;
import org.apache.mina.filter.codec.ProtocolCodecFilter;
import org.apache.mina.filter.codec.serialization.ObjectSerializationCodecFactory;
import org.apache.mina.filter.codec.textline.TextLineCodecFactory;
import org.apache.mina.transport.socket.nio.NioSocketConnector;

import java.net.InetSocketAddress;
import java.util.Scanner;

/**
 * mina客户端程序
 */
public class MinaClient {

    public static void main(String[] args) {

        /**创建一个mina客户端Socket连接器*/
        NioSocketConnector nioSocketConnector = new NioSocketConnector();

        /**获取过滤链*/
        DefaultIoFilterChainBuilder filterChain = nioSocketConnector.getFilterChain();

        /**添加一个行读取过滤器*/
        filterChain.addLast("defaultMinaFilter",new ProtocolCodecFilter(new ObjectSerializationCodecFactory()));

        /**添加一个消息处理器*/
        nioSocketConnector.setHandler(new DefaultClientMinaHandler());

        /**设置一个连接超时时间*/
        nioSocketConnector.setConnectTimeoutMillis(10000);

        /**连接一个服务端*/
        ConnectFuture connectFuture = nioSocketConnector.connect(new InetSocketAddress("localhost", 9999));

        /**等待连接成功*/
        connectFuture.awaitUninterruptibly();

        Scanner scanner = new Scanner(System.in);

        while (true){
            System.out.println("请输入:");
            String msg = scanner.nextLine();
            Message message = new Message();
            message.setId("1");
            message.setName(msg);
            connectFuture.getSession().write(message);
        }
    }
}

4.创建客服端的消息处理器

package com.imp4m.nio_io.mina;

import com.imp4m.nio_io.mina.domian.Message;
import org.apache.mina.core.service.IoHandlerAdapter;
import org.apache.mina.core.session.IoSession;

public class DefaultClientMinaHandler extends IoHandlerAdapter {

    @Override
    public void sessionOpened(IoSession session) throws Exception {
        super.sessionOpened(session);
        System.out.println("我已经连接成功了,"+session.getRemoteAddress());
    }


    @Override
    public void sessionClosed(IoSession session) throws Exception {
        super.sessionClosed(session);
        System.out.println("我已经和服务器["+session.getRemoteAddress()+"]断开连接");
    }

    @Override
    public void messageReceived(IoSession session, Object message) throws Exception {
        super.messageReceived(session, message);
        Message mes = (Message) message;
        System.out.println("服务返回消息:"+mes.getId()+"---"+mes.getName());
    }
}

5.创建传输对象java实体
注:传输对象可以是其它,如:字符串等

package com.imp4m.nio_io.mina.domian;

import java.io.Serializable;

/**
 * 消息对象
 */
public class Message implements Serializable {

    private String id;
    private String name;

    public String getId() {
        return id;
    }

    public void setId(String id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    @Override
    public String toString() {
        return "Message{" +
                "id='" + id + '\'' +
                ", name='" + name + '\'' +
                '}';
    }
}

猜你喜欢

转载自blog.csdn.net/xzpdskll/article/details/82285927