Socket+多线程,让发送消息和接收消息各占一条线程

在上次Socket通讯 使用Socket实现简单的聊天功能 中。客户端和服务器只有一方可以发送消息,另一方则只能等待(接收消息),而且不能连续发送消息。因为发送消息和接受消息共有一条线程,需要来回的切换。这时我们就要专门为发送消息接受消息各创建一个线程,就可以一次性发送多条消息。

步骤

1.创建一个发送消息Send类

package ThreadSocket;

import java.io.IOException;
import java.io.PrintWriter;
import java.net.Socket;
import java.util.Scanner;
/**
 * 发送消息类
 */
public class Send implements Runnable{
    private PrintWriter pw;
    private Socket socket;
    private String userName;//用户名(发送消息的对象)

    public Send() {    }

    public Send(Socket socket, String userName) {//传入Socket和用户名
        this.socket = socket;
        this.userName = userName;
    }

    @Override
    public void run() {
        String temp=new String();
        Scanner input=new Scanner(System.in);
        try {
            pw=new PrintWriter(socket.getOutputStream(),true);//打印流 通过Socket用于发送消息 

            while (true){
                temp=input.nextLine();
                pw.println(userName+":"+temp);//将消息发送出去
                if(temp.endsWith("bye"))//以bye结尾就退出
                    break;
            }

        } catch (IOException e) {
            e.printStackTrace();
        }finally {
            if(pw!=null)
            pw.close();
        }
    }
}

在run()里面不能直接throws,因为run()只是实现Runnable接口,接口中的run()并没有throws。因此只能try,自己处理异常 。

2.创建一个接收消息Reception类

package ThreadSocket;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.Socket;

/**
 * 接受消息类
 */
public class Reception implements Runnable {
    private Socket socket;

    private BufferedReader br;

    public Reception() {    }

    public Reception(Socket socket) {
        this.socket = socket;
    }

    @Override
    public void run() {
        String temp=new String();
        try {
            br=new BufferedReader(new InputStreamReader(socket.getInputStream()));//创建缓冲流 读取消息
            while (true){
                temp=br.readLine();
                System.out.println(temp);
                if(temp.endsWith("bye"))//以bye结尾就退出
                    break;
            }
        } catch (IOException e) {
            e.printStackTrace();
        }finally {
            try {
                if(br!=null)
                    br.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }


    }
}

3.创建服务器Server类,并开启发送消息和接受消息所在的线程

package ThreadSocket;

import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;

/**
 * 服务器端
 */
public class Server {
    public static void main(String[] args) throws IOException {
        ServerSocket server=new ServerSocket(6666);//创建服务器并指定端口号
        
        //开启监听
        Socket socket=server.accept();

        Thread send=new Thread(new Send(socket,"网管"));//创建线程
        Thread reception=new Thread(new Reception(socket));

        send.start();//开启线程
        reception.start();
    }
}

4.创建客户端Client类

package ThreadSocket;

import java.io.IOException;
import java.net.Socket;
/**
 * 客户端
 */
public class Client {
    public static void main(String[] args) throws IOException {
        Socket socket=new Socket("localhost",6666);//ip  和  端口号

        Thread  send       =new Thread(new Send(socket,"我"));
        Thread  reception  =new Thread(new Reception(socket));

        send.start();
        reception.start();
    }
}

5.先开启服务器端,然后开启客户端。

运行截图:


当我们开启两条线程时,发送消息和接受消息就互不干扰,这样用户体验感会好一点。

总结

在这个示例可能只是用两个类将Socket封装了一下,然后创建了两条线程。用到的知识点有:面向对象,IO流,多线程,Socket。当我们将学过的知识点组合起来使用时,好像慢慢的可以做出一些有趣的东西了。学习就是不断的总结与回顾,然后将学过的东西融会贯通的一个过程!


       每日鸡汤:那有什么岁月静好,不过有人替你负重前行。


Over!


猜你喜欢

转载自blog.csdn.net/Chianz632/article/details/80040014
今日推荐