java多线程socket通信原理是啥?

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了java多线程socket通信原理是啥?相关的知识,希望对你有一定的参考价值。

看到如下代码
public static void main(String[] args) throws IOException
ServerSocket server = new ServerSocket(10000);

while (true)
Socket socket = server.accept();
invoke(socket);



private static void invoke(final Socket socket) throws IOException
new Thread(new Runnable()
public void run()
ObjectInputStream is = null;
ObjectOutputStream os = null;
当端口收到请求后,直接以这个监听对象开了一个新线程。求解释?
如果有多个客户同时与服务器通信,服务器程序只监听10000这一个端口,如何靠这个socket对象区分是哪个客户发来的会话?是因为每个socket都有自己的id吗?不懂

第一,程序是通过分时进行服务的。就是说一个程序监听一个端口,第一秒可以从别的地方来一个包,第二秒可以从另一个地方来一个包。
第二,每个socket都会有包发送来的ip地址和端口号,服务器向这个ip对应机器的端口发送数据以回应对方。
参考技术A 简单点说, 每个socket都保有一些信息, 比如他所对应的客户端地址和端口等等, 来唯一确定他所负责的客户端, 所以任何到达10000端口的包都可以有去处: 如果已经有socket和他对应了, 那么交给socket处理, 如果没有, 那么放进请求队列, 等待.accept()方法去抽取他并生成一个socket来和他对应. 参考技术B 当Server每接受到一个Client连接请求之后,都把处理流程放到一个独立的线程里去运行,然后等待下一个Client连接请求,这样就不会阻塞Server端接收请求了。每个独立运行的程序在使用完Socket对象之后要将其关闭。这样就实现了多线程socket通信。 参考技术C socket 需要 把自己的 ip 告诉ServerSocket,就是根据ip来区分的 参考技术D 防止阻塞

如果不用线程,你在主线程中侦听端口,
那么你会发现,你如果不连接上的话,就会一直在等待,什么也做不了。

java多线程实现多客户端socket通信

一、服务端

package com.czhappy.hello.socket;

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

public class Server {
    public static void main(String[] args) {
        //创建ServerSocket示例,指定端口,侦听
        try {
            ServerSocket serverSocket = new ServerSocket(8888);
            System.out.println("服务即将启动,等待客户端连接");
            //记录客户端的数量
            int count = 0;
            Socket socket = null;
            while(true){
                //开始监听,等待客户端的连接
                socket = serverSocket.accept();
                ServerThread serverThread = new ServerThread(socket);
serverThread.setPriority(4);//设置线程的优先级,范围是:[1,10],默认为5 serverThread.start(); count
++; System.out.println("客户端的数量="+count); InetAddress address = socket.getInetAddress(); System.out.println("当前客户端的IP地址为:"+address.getHostAddress()); } } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } }
package com.czhappy.hello.socket;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.io.UnsupportedEncodingException;
import java.net.Socket;

/**
 * 服务器线程处理类
 * @author Administrator
 *
 */
public class ServerThread extends Thread{
    
    Socket socket = null;
    
    public ServerThread(Socket socket){
        this.socket = socket;
    }
    
    public void run() {
        InputStream is = null;
        InputStreamReader isr = null;
        BufferedReader br = null;
        OutputStream os = null;
        PrintWriter pw = null;
        try {
            //获取字节输入流
            is = socket.getInputStream();
            //将字节输入流转化为字符输入流
            isr = new InputStreamReader(is, "utf-8");
            //为字符输入流添加缓冲
            br = new BufferedReader(isr);
            String data = br.readLine();
            while(data!=null){
                System.out.println("我是服务器,客户端说:"+data);
                data = br.readLine();
            }
            //关闭输入流
            socket.shutdownInput();
            //获取输出流,响应客户端请求
            os = socket.getOutputStream();
            pw = new PrintWriter(os);
            pw.write("欢迎您!");
            pw.flush();
        } catch (UnsupportedEncodingException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }finally{
            try {
                if(pw!=null){
                    pw.close();
                }
                if(os!=null){
                    os.close();
                }
                if(br!=null){
                    br.close();
                }
                if(isr!=null){
                    isr.close();
                }
                if(is!=null){
                    is.close();
                }
                if(socket!=null){
                    socket.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        
    }

}

二、客户端

package com.czhappy.hello.socket;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.net.Socket;
import java.net.UnknownHostException;

public class Client {
    
    public static void main(String[] args) {
        try {
            //创建客户端Socket,指定服务器地址和端口
            Socket socket = new Socket("192.168.0.45", 8888);
            //获取输出流,向服务器发送消息
            OutputStream os = socket.getOutputStream();//字节输出流
            PrintWriter pw = new PrintWriter(os);//将输出流包装成打印流
            pw.write("用户名:admin;密码:123");
            pw.flush();
            socket.shutdownOutput();//关闭输出流
            //获取输入流,读取服务器端响应信息
            InputStream is = socket.getInputStream();
            BufferedReader br = new BufferedReader(new InputStreamReader(is));
            String data = br.readLine();
            while(data!=null){
                System.out.println("我是客户端,服务器说:"+data);
                data = br.readLine();
            }
            
            br.close();
            is.close();
            pw.close();
            os.close();
            socket.close();
        } catch (UnknownHostException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }
    
    

}

三、测试结果

需要先启动服务端,再启动客户端

服务端运行结果:

客户端运行结果:

以上是关于java多线程socket通信原理是啥?的主要内容,如果未能解决你的问题,请参考以下文章

Java 多线程 用socket通信

Java千百问_02基本使用(012)_如何编写多线程Socket程序

Java Socket 通信之多线程

Java Socket实现基于TCP和UDP多线程通信

应用java多线程实现server端与多client之间的通信

Java多线程:线程间通信方式