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

在上次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!


  • 7
    点赞
  • 20
    收藏
    觉得还不错? 一键收藏
  • 11
    评论
可以使用Python中的`threading`模块来实现多线程同时接收发送TCP消息。具体实现步骤如下: 1. 创建一个`socket`对象,并绑定到本地端口上,等待客户端连接。 ```python import socket server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) server_socket.bind(('localhost', 8888)) server_socket.listen(5) ``` 2. 创建一个线程函数来处理客户端的请求。 ```python import threading def handle_client(client_socket): while True: data = client_socket.recv(1024) if not data: break client_socket.send(data) client_socket.close() ``` 在这个线程函数中,我们通过`recv()`函数接收客户端发送过来的数据,并使用`send()`函数将数据发送回客户端。如果客户端关闭了连接,我们就退出循环,并关闭客户端套接字。 3. 在主线程中,使用`accept()`函数接受客户端连接,并创建一个新的线程来处理客户端请求。 ```python while True: client_socket, client_address = server_socket.accept() print('New connection from', client_address) client_thread = threading.Thread(target=handle_client, args=(client_socket,)) client_thread.start() ``` 每当有一个新的客户端连接进来,我们就打印一条信息,并创建一个新的线程来处理这个客户端的请求。新线程的目标函数就是我们前面定义的`handle_client()`函数。 完整的代码如下: ```python import socket import threading def handle_client(client_socket): while True: data = client_socket.recv(1024) if not data: break client_socket.send(data) client_socket.close() server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) server_socket.bind(('localhost', 8888)) server_socket.listen(5) while True: client_socket, client_address = server_socket.accept() print('New connection from', client_address) client_thread = threading.Thread(target=handle_client, args=(client_socket,)) client_thread.start() ``` 这个服务器程序可以同时处理多个客户端请求,每个客户端都会在独立的线程中被处理。注意,在真实的生产环境中,我们需要考虑一些线程安全的问题,比如共享资源的竞争问题等。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 11
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值