Java|Socket编程指南

概述

Socket编程是指编写在多台计算机上执行的程序,其中的设备都使用网络相互连接

Socket常用的通信协议有UDP和TCP,本文主要介绍通过TCP/IP网络协议进行Socket编程

Socket通信流程

img

  • 服务端和客户端初始化 socket,得到文件描述符;
  • 服务端调用 bind,将绑定在 IP 地址和端口;
  • 服务端调用 listen,进行监听;
  • 服务端调用 accept,等待客户端连接;
  • 客户端调用 connect,向服务器端的地址和端口发起连接请求;
  • 服务端 accept 返回用于传输的 socket 的文件描述符;
  • 客户端调用 write 写入数据;服务端调用 read 读取数据;
  • 客户端断开连接时,会调用 close,那么服务端 read 读取数据的时候,就会读取到了 EOF,待处理完数据后,服务端调用 close,表示连接关闭;

服务端调用 accept 时,连接成功了会返回一个已完成连接的 socket,后续用来传输数据。所以,监听的 socket 和真正用来传送数据的 socket,是「两个」 socket,一个叫作监听 socket,一个叫作已完成连接 socket

简单示例

Socket是网络上不同计算机运行的两个程序之间双向通信链路的一个端点。Socket需要绑定端口号,一遍传输层可以标识数据要发送到的应用程序

服务端

服务端会用到两个socket,一个叫作监听 socket,一个叫作已完成连接 socket

目前的服务器不能保证通信的连续性,它会在发送完消息后关闭连接

import java.io.*;
import java.net.ServerSocket;
import java.net.Socket;

// socket服务端
public class Server {
   
    private ServerSocket serverSocket;
    private Socket clientSocket;
    private PrintWriter out;
    private BufferedReader in;

    public void start(int port){
   
        try{
   
            // (监听socket)
            // 绑定指定端口,使服务器的Socket在指定端口号上运行
            serverSocket = new ServerSocket(port);

            // (已连接socket)
            // 服务器遇到accept进入阻塞,等待客户端发出连接
            // 连接成功后,服务器将获得绑定到同一本地端口6666的新socket,用于传输数据
            clientSocket = serverSocket.accept();

            // 输出流,可发送消息到客户端
            out = new PrintWriter(clientSocket.getOutputStream(), true);
            // 输入流,可接收客户端消息
            in = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));

            String greeting = in.readLine();

            if(greeting.equals("hello server")){
   
                out.println("hello client");
            }
            else{
   
                out.println("unrecognised greeting");
            }

        }
        catch (IOException e){
   
            e.printStackTrace();
        }


    }

    public void stop(){
   
        try{
   
            in.close();
            out.close();
            clientSocket.close();
            serverSocket.close();

        }
        catch (IOException e){
   
            e.printStackTrace();
        }


    }

    public static void main(String[] args) {
   
        Server server = new Server();
        // 开启服务器
        server.start(6666);
    }

}

客户端

客户端只需要创建一个socket以保持连接,最终客户端的输入流连接到服务端的输出流,服务器的输入流连接到客户端的输出流

import com.sun.javafx.iio.ios.IosDescriptor;

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

public class Client {
   
    private Socket clientSocket;
    private PrintWriter out;
    private BufferedReader in;

    public void startConnection(String ip, int port){
   

        try{
   
            // 客户端需要知道服务端的ip和其正在监听的端口号,才能发起连接
            // 服务器接收连接后创建客户端socket
            clientSocket = new Socket(ip, port);

            // 获取socket的输入输出流,以便与服务端通信
            out = new PrintWriter(clientSocket.getOutputStream(), true);
            in = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));
        }
        catch (IOException e){
   
            e.printStackTrace();
        }



    }

    
  • 2
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值