网络编程(三)——基于Socket的Java网络编程

                                     基于Socket的Java网络编程

1,什么是Socket

  网络上的两个程序通过一个双向的通讯连接实现数据的交换,这个双向链路的一端称为一个Socket。Socket通常用来实现客户方和服务方的连接。Socket是TCP/IP协议的一个十分流行的编程界面,一个Socket由一个IP地址和一个端口号唯一确定。但是,Socket所支持的协议种类也不光TCP/IP一种,因此两者之间是没有必然联系的。在Java环境下,Socket编程主要是指基于TCP/IP协议的网络编程。

TCP通信同UDP通信一样,都能实现两台计算机之间的通信,通信的两端都需要创建socket对象。

区别在于,UDP中只有发送端和接收端,不区分客户端与服务器端,计算机之间可以任意地发送数据。

而TCP通信是严格区分客户端与服务器端的,在通信时,必须先由客户端去连接服务器端才能实现通信,服务器端不可以主动连接客户端,并且服务器端程序需要事先启动,等待客户端的连接。

2,Socket通讯的过程

  Server端Listen(监听)某个端口是否有连接请求,Client端向Server 端发出Connect(连接)请求,Server端向Client端发回Accept(接受)消息。一个连接就建立起来了。Server端和Client 端都可以通过Send,Write等方法与对方通信。

  对于一个功能齐全的Socket,都要包含以下基本结构,其工作过程包含以下四个基本的步骤:

  (1)创建Socket;

  (2)打开连接到Socket的输入/出流;

  (3)按照一定的协议对Socket进行读/写操作;

  (4)关闭Socket.

在JDK中提供了两个类用于实现TCP程序,一个是ServerSocket类,用于表示服务器端,一个是Socket类,用于表示客户端

通信时,首先创建代表服务器端的ServerSocket对象,该对象相当于开启一个服务,并等待客户端的连接,然后创建代表客户端的Socket对象向服务器端发出连接请求,服务器端响应请求,两者建立连接开始通信。

 

3、ServerSocket

该类的实例对象可以实现一个服务器端的程序

1)构造方法

  • ServerSocket()                                                                       创建非绑定服务器套接字。
  • ServerSocket(int port)                                                            创建绑定到特定端口的服务器套接字。
  • ServerSocket(int port, int backlog)                                         利用指定的 backlog 创建服务器套接字并将其绑定到指定的本地端口号。
  • ServerSocket(int port, int backlog, InetAddress bindAddr)     使用指定的端口、侦听 backlog (最大的等待队列)和要绑定到的本地 IP 地址创建服务器。

2)方法

(1)绑定地址

  • bind(SocketAddress endpoint)   void            将 ServerSocket 绑定到特定地址(IP 地址和端口号)。
  • bind(SocketAddress endpoint, int backlog)  void    将 ServerSocket 绑定到特定地址(IP 地址和端口号)。
  • isBound()  boolean                                                 返回套接字的绑定状态。 

 (2)获取地址

  • getInetAddress()   InetAddress            返回此服务器套接字的本地地址。
  • getLocalPort()   int                返回此套接字在其上侦听的端口。
  • getLocalSocketAddress()  SocketAddress     返回此套接字绑定的端点的地址,如果尚未绑定则返回 null。

(3)设置缓冲区

  • setReceiveBufferSize(int size) void            将此 Socket 的 SO_RCVBUF 选项设置为指定的值。 
  • setSendBufferSize(int size) void         将此 Socket 的 SO_SNDBUF 选项设置为指定的值。

(4)重用端口

  • setReuseAddress(boolean on) void      启用/禁用 SO_REUSEADDR 套接字选项。 
  • getReuseAddress()   boolean               测试是否启用 SO_REUSEADDR。

(5)接受连接

  • accept()   Socket     侦听并接受到此套接字的连接。

(6)关闭

  • close()  void                    关闭此套接字。
  • isClosed()  boolean       返回套接字的关闭状态。

ServerSocket对象负责监听某台计算机的某个端口号,在创建ServerSocket对象后,需要继续调用该对象的accept()方法,接收来自客户端的请求。当执行了accept()方法之后,服务器端程序会发生阻塞,直到客户端发出连接请求,accept()方法才会返回一个Scoket对象用于和客户端实现通信,程序才能继续向下执行。

 

4、Socket

JDK提供了一个Socket类,用于实现TCP客户端程序

(1)构造方法

  • Socket()                                                                       通过系统默认类型的 SocketImpl 创建未连接套接字
  • Socket(InetAddress address, int port)                                                            创建一个流套接字并将其连接到指定 IP 地址的指定端口号。
  • Socket(InetAddress address, int port, InetAddress localAddr, int localPort)        创建一个套接字并将其连接到指定远程地址上的指定远程端口。
  • Socket(Proxy proxy)                                                                                            创建一个未连接的套接字并指定代理类型(如果有),该代理不管其他设置如何都应被使用。
  • Socket(String host, int port)                                                                                 创建一个流套接字并将其连接到指定主机上的指定端口号。
  • Socket(String host, int port, InetAddress localAddr, int localPort)                        创建一个套接字并将其连接到指定远程主机上的指定远程端口。

(2)成员方法

1)关联地址

  • bind(SocketAddress bindpoint)  void           将套接字绑定到本地地址。
  • connect(SocketAddress endpoint)   void        将此套接字连接到服务器。
  • connect(SocketAddress endpoint, int timeout)    void         将此套接字连接到服务器,并指定一个超时值。
  • isBound()  boolean           返回套接字的绑定状态。 
  • isConnected()  boolean    返回套接字的连接状态。

2)获取IP地址

  • getInetAddress()   InetAddress          返回套接字连接的地址。 
  • getLocalAddress()   InetAddress        获取套接字绑定的本地地址。
  • getPort()            int    返回此套接字连接到的远程端口。
  • getLocalPort()      int 返回此套接字绑定到的本地端口。
  • getLocalSocketAddress()  SocketAddress 返回此套接字绑定的端点的地址,如果尚未绑定则返回 null。 
  • getRemoteSocketAddress()   SocketAddress 返回此套接字连接的端点的地址,如果未连接则返回 null。

3)获取数据

  • getInputStream()   InputStream           返回此套接字的输入流。 
  • getOutputStream()   OutputStream     返回此套接字的输出流。
  • getChannel()   SocketChannel            返回与此数据报套接字关联的唯一 SocketChannel 对象(如果有)。

4)设置缓冲区

  • setReceiveBufferSize(int size) void            将此 Socket 的 SO_RCVBUF 选项设置为指定的值。 
  • setSendBufferSize(int size) void         将此 Socket 的 SO_SNDBUF 选项设置为指定的值。

5)重用端口

  • setReuseAddress(boolean on) void      启用/禁用 SO_REUSEADDR 套接字选项。 
  • getReuseAddress()   boolean               测试是否启用 SO_REUSEADDR。

6)关闭

  • close()  void                    关闭此套接字。
  • isClosed()  boolean       返回套接字的关闭状态。

 

5、简单的TCP网络程序

服务器端和客户端的数据传输:

                                          

 

要实现TCP通信需要创建一个服务器端程序和一个客户端程序,为了保证数据传输的安全性,首先需要实现服务器端程序

1) 服务端

package com.sxb.socket.common.server;

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

/**
 * @Description socket服务端基础类:
 *              服务端监听一个端口,等待连接的到来,服务端只能被动的接收客户端的请求,不能发送响应
 * @Author ShiXinbing
 * @Date 2018/7/25 0025 15:21
 * @Version 1.0
 **/
public class SocketServer {
    public static void main(String[] args) throws IOException {

        // 1 监听指定的端口号
        int port = 55533;
        // 2 创建ServerSocket对象
        ServerSocket server = new ServerSocket(port);

        // 3 开启server,将一直等待client的请求连接的到来
        System.out.println("server将一直等待连接的到来。。。。。");
        Socket socket = server.accept();

        // 4 建立好连接后,从socket中获取输入流,并建立缓冲区进行读取
        InputStream inputStream = socket.getInputStream();

        byte[] bytes = new byte[1024];
        int len;
        StringBuilder sb = new StringBuilder();
        while ((len = inputStream.read(bytes)) != -1) {
            //注意指定编码格式,发送方和接收方一定要统一,建议使用UTF-8
            sb.append(new String(bytes, 0, len, "UTF-8"));
        }

        System.out.println("get message from client: " + sb);

        // 关闭资源
        inputStream.close();
        socket.close();
        server.close();
    }
}

2)客户端

package com.sxb.socket.common.client;

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

/**
 * @Description 客户端通过ip和端口,连接到指定的server,然后通过Socket获得输出流,并向其输出内容,
 *              服务器会获得消息。客户端只能发送请求,不能接收响应
 * @Author ShiXinbing
 * @Date 2018/7/25 0025 15:39
 * @Version 1.0
 **/
public class SocketClient {
    public static void main(String[] args) throws IOException {
        // 1 要连接的服务端IP地址和端口
        String ip = "127.0.0.1";
        int port = 55533;

        // 2 创建客户端对象,与服务端建立连接
        Socket socket = new Socket(ip, port);

        // 3 建立连接后获得输出流
        OutputStream outputStream = socket.getOutputStream();
        String message = "你好  shiXinBing !!!";
        outputStream.write(message.getBytes("UTF-8"));

        System.out.println("消息已发送。。。。。");

        // 4 关闭资源
        outputStream.close();
        socket.close();
    }
}

 

 

 

 

 

猜你喜欢

转载自blog.csdn.net/shixinbing/article/details/81216877
今日推荐