关于Java Socket的使用以及多线程的客户端和服务器端之间的通信

关于Java Socket的使用以及多线程的客户端和服务器端之间的通信

Java的Socket与ServerSocket

Socket
指的是能够通过指定的ip和端口号与服务器互相通信的一个客户端/套接字,通常我们都用它来充当客户端。

ServerSocket
顾名思义,就是服务器用的一个套接字,用来接收连接到指定端口号的客户端/套接字。

Socke类 里面有几个比较重要的方法:

  1. 两参构造函数 Socket(String ip,int port)
    我们能用它来创建一个连接到指定ip和端口号的套接字,用于与服务器通信
  2. 输出流 getOutputStream() 以及输入流 getInputStream()
    我们可以用这两个方法来获取 客户端向服务器的请求 以及 来自服务器的响应
  3. Socket关闭方法 close()
    我们可以用此方法关掉不用的通信,并释放相应的资源

ServerSocket类 里面也有几个比较重要的方法:

  1. 一参构造函数 ServerSocket(int port)
    我们能用它来 创建一个监听指定端口号的服务器套接字,用于监听客户端的通信
  2. 获取客户端Socket的函数 accept()
    我们可以用这个方法来获取 新连接上的客户端 。但是要注意,这个方法是以 阻塞的方式 来运行的,也就是一旦我们调用了这个方法,调用它的线程就会进入阻塞状态,一直等待客户端的连接。而服务器一般需要 同时提供多个客户端的连接需求,故我们一般会同时使用 多线程 来提高服务器的带机量。
  3. ServerSocket关闭方法 close()
    我们可以用此方法关掉不用的服务器套接字,并释放相应的资源

多线程

在没学习多线程之前,我一直以为多线程肯定可以提升程序的运行速度,学完之后才发现,它不一定可以提升程序的运行速度,但是可以提高程序运行的效率,就好比一个人干活和一群人干活哪个效率高一样,多线程可以让我们的程序同时干多件事情,同时它也会带来线程安全的问题:

  1. Java的多线程有三种实现方式 ,分别是:
    (1) 继承Thread类,重写run()方法
public class Test {
   
    public static void main(String[] args) {
   
        MyThread t = new MyThread();
        t.start();
    }
}

class MyThread extends Thread {
   
    private void say() {
   
        System.out.println(Thread.currentThread().getName() + " hello java");
    }

    @Override
    public void run() {
   
        say();
    }
}

(2) 实现Runnable接口,实现run()方法

public class Test {
   
    public static void main(String[] args) {
   
        MyRunnable r = new MyRunnable();
        new Thread(r).start();
    }
}

class MyRunnable implements Runnable {
   
    private void say() {
   
        System.out.println(Thread.currentThread().getName() + " hello java");
    }

    @Override
    public void run() {
   
        say();
    }
}

(3) 实现Callable接口,实现call()方法

public class Test {
   
    public static void main(String[] args) {
   
        MyCallable r = new MyCallable();
        FutureTask f = new FutureTask(r);
        new Thread(f).start();
        try {
   
            System.out.println(r.call());
        } catch (Exception e) {
   
            e.printStackTrace();
        }
    }
}

class MyCallable implements Callable {
   
    private void say() {
   
        System.out.println(Thread.currentThread().getName() + " hello java");
    }

    @Override
    public Object call() throws Exception {
   
        say();
        Thread.sleep(1000*5);
        return "call is execute";
    }
}
//输出
main hello java
//若不调用call()方法,则和普通的Runnable一样
Thread-0 hello java
//若调用call()方法,则调用者会等待其返回结果
call is execute

因为都是无参方法,可以使用lambda表达式进行简化。

new Thread(()->{
   
	//里面相当于run
    System.out.println(Thread.currentThread().getName()+"已经启动!");
}).start();

使用案例

这是我写的一个服务器端和一个客户端,这里面都使用到了多线程。

客户端

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

public class MyClient implements Runnable{
   
    private Socket client;
    public MyClient(String ip,int port){
   
        //判断如果ip不为空,且端口号大于0 小于65536
        if(!ip.isEmpty() && port>0 && port<65536) 
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值