Java学习记录——高级:网络编程socket、多线程编程

Java 网络编程

java.net 包中提供了两种常见的网络协议的支持:
TCP/UDP

TCP:TCP(英语:Transmission Control Protocol,传输控制协议) 是一种面向连接的、可靠的、基于字节流的传输层通信协议,TCP 层是位于 IP 层之上,应用层之下的中间层。TCP 保障了两个应用程序之间的可靠通信。通常用于互联网协议,被称 TCP / IP。

UDP:UDP (英语:User Datagram Protocol,用户数据报协议),位于 OSI 模型的传输层。一个无连接的协议。提供了应用程序之间要发送数据的数据报。由于UDP缺乏可靠性且属于无连接协议,所以应用程序通常必须容许一些丢失、错误或重复的数据包。

socket编程

套接字使用TCP提供了两台计算机之间的通信机制。 客户端程序创建一个套接字,并尝试连接服务器的套接字。

当连接建立时,服务器会创建一个 Socket 对象。客户端和服务器现在可以通过对 Socket 对象的写入和读取来进行通信。

java.net.Socket 类代表一个套接字,并且 java.net.ServerSocket 类为服务器程序提供了一种来监听客户端,并与他们建立连接的机制。

以下步骤在两台计算机之间使用套接字建立TCP连接时会出现:

  • 服务器实例化一个 ServerSocket 对象,表示通过服务器上的端口通信。

  • 服务器调用 ServerSocket 类的 accept() 方法,该方法将一直等待,直到客户端连接到服务器上给定的端口。

  • 服务器正在等待时,一个客户端实例化一个 Socket 对象,指定服务器名称和端口号来请求连接。

  • Socket 类的构造函数试图将客户端连接到指定的服务器和端口号。如果通信被建立,则在客户端创建一个 Socket 对象能够与服务器进行通信。

  • 在服务器端,accept() 方法返回服务器上一个新的 socket 引用,该 socket 连接到客户端的 socket。

ServerSocket 类的方法

ServerSocket 类有四个构造方法:

1	public ServerSocket(int port) throws IOException
创建绑定到特定端口的服务器套接字。
2	public ServerSocket(int port, int backlog) throws IOException
利用指定的 backlog 创建服务器套接字并将其绑定到指定的本地端口号。
3	public ServerSocket(int port, int backlog, InetAddress address) throws IOException
使用指定的端口、侦听 backlog 和要绑定到的本地 IP 地址创建服务器。
4	public ServerSocket() throws IOException
创建非绑定服务器套接字。

常用方法:

public int getLocalPort()
//用于返回此套接字在其上侦听的端口
public Socket accept() throws IOException
//侦听并接收到此套接字的连接
public void setSoTimeout(int timeout)
//指定超时值以启用或者禁用SO_TIMEOUT(以毫秒为单位)
public void bind(SocketAddress host,int backlog)
//绑定到特定地址(IP地址和端口号)

Socket 类的方法

java.net.Socket 类代表客户端和服务器都用来互相沟通的套接字。客户端要获取一个 Socket 对象通过实例化 ,而 服务器获得一个 Socket 对象则通过 accept() 方法的返回值。

socket类的五种构造方法:

1	public Socket(String host, int port) throws UnknownHostException, IOException.
创建一个流套接字并将其连接到指定主机上的指定端口号。

2	public Socket(InetAddress host, int port) throws IOException
创建一个流套接字并将其连接到指定 IP 地址的指定端口号。

3	public Socket(String host, int port, InetAddress localAddress, int localPort) throws IOException.
创建一个套接字并将其连接到指定远程主机上的指定远程端口。

4	public Socket(InetAddress host, int port, InetAddress localAddress, int localPort) throws IOException.
创建一个套接字并将其连接到指定远程地址上的指定远程端口。

5	public Socket()
通过系统默认类型的 SocketImpl 创建未连接套接字

当 Socket 构造方法返回,并没有简单的实例化了一个 Socket 对象,它实际上会尝试连接到指定的服务器和端口。

Socket类的方法:

1	public void connect(SocketAddress host, int timeout) throws IOException
将此套接字连接到服务器,并指定一个超时值。
2	public InetAddress getInetAddress()
 返回套接字连接的地址。
3	public int getPort()
返回此套接字连接到的远程端口。
4	public int getLocalPort()
返回此套接字绑定到的本地端口。
5	public SocketAddress getRemoteSocketAddress()
返回此套接字连接的端点的地址,如果未连接则返回 null。
6	public InputStream getInputStream() throws IOException
返回此套接字的输入流。
7	public OutputStream getOutputStream() throws IOException
返回此套接字的输出流。
8	public void close() throws IOException
关闭此套接字。

InetAddress 类的方法

这个类表示互联网协议(IP)地址。(InetAddress)
方法:

1	static InetAddress getByAddress(byte[] addr)
在给定原始 IP 地址的情况下,返回 InetAddress 对象。
2	static InetAddress getByAddress(String host, byte[] addr)
根据提供的主机名和 IP 地址创建 InetAddress。
3	static InetAddress getByName(String host)
在给定主机名的情况下确定主机的 IP 地址。
4	String getHostAddress() 
返回 IP 地址字符串(以文本表现形式)。
5	String getHostName() 
 获取此 IP 地址的主机名。
6	static InetAddress getLocalHost()
返回本地主机。
7	String toString()
将此 IP 地址转换为 String。

多线程编程

创建一个线程
Java 提供了三种创建线程的方法:

通过实现 Runnable 接口;
通过继承 Thread 类本身;
通过 Callable 和 Future 创建线程。

通过实现 Runnable 接口来创建线程
最简单的方法:

public void run()

你可以重写该方法,重要的是理解的 run() 可以调用其他方法,使用其他类,并声明变量,就像主线程一样。

在创建一个实现 Runnable 接口的类之后,你可以在类中实例化一个线程对象。

Thread 定义了几个构造方法,下面的这个是我们经常使用的:

Thread(Runnable threadOb,String threadName);

通过继承Thread来创建线程
创建一个线程的第二种方法是创建一个新的类,该类继承 Thread 类,然后创建一个该类的实例。

继承类必须重写 run() 方法,该方法是新线程的入口点。它也必须调用 start() 方法才能执行。

该方法尽管被列为一种多线程实现方式,但是本质上也是实现了 Runnable 接口的一个实例。

ThreadDemo T1 = new ThreadDemo( "Thread-1");
      T1.start();
      
      ThreadDemo T2 = new ThreadDemo( "Thread-2");
      T2.start();

Thread类的一些方法

1	public void start()
使该线程开始执行;Java 虚拟机调用该线程的 run 方法。
2	public void run()
如果该线程是使用独立的 Runnable 运行对象构造的,则调用该 Runnable 对象的 run 方法;否则,该方法不执行任何操作并返回。
3	public final void setName(String name)
改变线程名称,使之与参数 name 相同。
4	public final void setPriority(int priority)
 更改线程的优先级。
5	public final void setDaemon(boolean on)
将该线程标记为守护线程或用户线程。
6	public final void join(long millisec)
等待该线程终止的时间最长为 millis 毫秒。
7	public void interrupt()
中断线程。
8	public final boolean isAlive()
测试线程是否处于活动状态。

上述方法是被 Thread 对象调用的,下面方法是 Thread 类的静态方法。

1	public static void yield()
暂停当前正在执行的线程对象,并执行其他线程。
2	public static void sleep(long millisec)
在指定的毫秒数内让当前正在执行的线程休眠(暂停执行),此操作受到系统计时器和调度程序精度和准确性的影响。
3	public static boolean holdsLock(Object x)
当且仅当当前线程在指定的对象上保持监视器锁时,才返回 true。
4	public static Thread currentThread()
返回对当前正在执行的线程对象的引用。
5	public static void dumpStack()
将当前线程的堆栈跟踪打印至标准错误流。

通过 Callable 和 Future 创建线程

  1. 创建 Callable 接口的实现类,并实现 call() 方法,该 call() 方法将作为线程执行体,并且有返回值。

  2. 创建 Callable 实现类的实例,使用 FutureTask 类来包装 Callable 对象,该 FutureTask 对象封装了该 Callable 对象的 call() 方法的返回值。

  3. 使用 FutureTask 对象作为 Thread 对象的 target 创建并启动新线程。

  4. 调用 FutureTask 对象的 get() 方法来获得子线程执行结束后的返回值。

创建线程的三种方式的对比

  1. 采用实现 Runnable、Callable 接口的方式创建多线程时,线程类只是实现了 Runnable 接口或 Callable 接口,还可以继承其他类。

  2. 使用继承 Thread 类的方式创建多线程时,编写简单,如果需要访问当前线程,则无需使用 Thread.currentThread() 方法,直接使用 this 即可获得当前线程。

上一篇:java基础-泛型


下一篇:POI根据模板生成新的Excel文件