Socket实现简单的TCP通信

3 篇文章 1 订阅

Socket编程

基本介绍

工作原理

Socket中TCP的三次握手建立连接

Socket中TCP的四次挥手释放连接

实现简单的TCP使用

服务端Server

客户端Client


Socket编程

基本介绍

Socket又称“套接字”,原意为“孔”或“插座”。Socket像是一个多孔的插座,是操作系统暴露给应用层的插座,应用层能够通过Socket使用操作系统提供的TCP,UDP等服务。

 如果说socket是一个多孔插座,插座是提供各种电器供电的地方,不同的电器工作时需要的电压和电流也不一样,但各种电器都有各自的一个插口,这个称之为“端口”。电器使用的电可以看做是网络资源或者是各种“流”,电是由电线传输过来的,所以插座需要连接电线,这里电线也就是服务器和客户端连接  “connection”。 其中初始化socket的过程像是买来一个插座的安装过程。

在插座这边的是“客户端”,电线那边提供电的发电厂是“服务器”。客户端和发电厂都各自拥有一个地址,即“IP地址”。其中还有一套传输和用电的规则,比如传输电时需要的电线多少伏才能满足需求,电器用电的技术参数,端口是几个孔的。这个是“协议”。正常情况下我们是不会去管协议的内容是什么,也就是说协议在我们面前是隐藏的。

上述引用转摘自:https://www.cnblogs.com/liusxg/p/3917624.html

Socket在哪里呢???

工作原理

服务器端先初始化Socket,然后与端口进行绑定,对端口进行监听(listen),调用accept阻塞,等待客户端连接。

此时如果有个客户端初始化一个Socket,然后申请连接服务器,如果连接成功,客户端与服务器端的连接就建立了。

客户端发送请求数据,服务端接收请求并处理请求,然后把回应数据发送给客户端,科幻段读取数据,最后关闭连接,一次交互结束。

Socket中TCP的三次握手建立连接

TCP建立连接要进行“三次握手”

客户端向服务器发送一个SYN

服务端向客户端响应一个SYN,并对SYN进行确认ACK

客户端再向服务器发送一个确认ACK

当客户端调用connect时,触发了连接请求,向服务器发送了SYN 包,这时connect进入阻塞状态;

服务器监听到连接请求,即收到SYN J包,调用accept函数接收请求向客户端发送SYN  ,ACK ,这时accept进入阻塞状态;

客户端收到服务器的SYN  ,ACK之后,这时connect返回,并对SYN 进行确认;

服务器收到ACK 时,accept返回,至此三次握手完毕,连接建立。

服务器端的accept在三次握手的第三次返回。

accept返回,代表已经建立好了一条TCP连接,三次握手结束了。

Socket中TCP的四次挥手释放连接

image

  • 应用进程首先调用close主动关闭连接,这时TCP发送一个FIN M;

  • 另一端接收到FIN M之后,执行被动关闭,对这个FIN进行确认。它的接收也作为文件结束符传递给应用进程,因为FIN的接收意味着应用进程在相应的连接上再也接收不到额外数据;

  • 一段时间之后,接收到文件结束符的应用进程调用close关闭它的socket。这导致它的TCP也发送一个FIN N;

  • 接收到这个FIN的源发送端TCP对它进行确认。

实现简单的TCP使用

使用到的两个类:

java.net.ServerSocket——服务端做三次握手之前监听使用

java.net.Socket——1.客户端;2.服务端,已经建立好的连接

服务端Server

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

public class Server {
    public static void main(String[] args) throws IOException {
        //服务端,需要监听一个固定的端口
        ServerSocket serverSocket = new ServerSocket(8080);
        while (true){
            //三次握手在accept的过程中完成
            Socket socket = serverSocket.accept();
            //此时socket代表已经建立好了一条TCP连接
            System.out.println("有一条TCP连接已经建立");
            
            //通过inputStream,读取client发送过来的应用层数据
            InputStream inputStream = socket.getInputStream();
            Scanner scanner = new Scanner(inputStream,"UTF-8");
            String line = scanner.nextLine();//先读取客户端发来的消息
            System.out.println(line);
            
            //将数据写入outputStream ,发送给客户端
            OutputStream outputStream = socket.getOutputStream();
            Writer writer = new OutputStreamWriter(outputStream,"UTF-8");
            PrintWriter printWriter = new PrintWriter(writer);
            printWriter.printf("项目\r\n");

            printWriter.flush();//刷新之后,才能把数据真正的写入

            //触发四次挥手
            socket.close();
            //四次挥手结束
        }

    }
}

客户端Client

import java.io.*;
import java.net.Socket;
import java.util.Scanner;
public class Client {
    public static void main(String[] args) throws IOException {
        Socket socket = new Socket("localhost",8080);
        //socket已经建立好连接

        InputStream inputStream = socket.getInputStream();
        Scanner scanner = new Scanner(inputStream,"UTF-8");

        OutputStream outputStream = socket.getOutputStream();
        Writer writer = new OutputStreamWriter(outputStream,"UTF-8");
        PrintWriter printWriter = new PrintWriter(writer);//向服务器发送消息
        printWriter.printf("Hello,Java\r\n");
        printWriter.flush();

        String message = scanner.nextLine();//从服务器读取
        System.out.println(message);


        socket.close();
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值