Java网络编程(四) —— TCP实现数据传输

UDP和TCP进行java编程区别

接口使用

udp套接字使用DatagramSocket实现发送和接收
而TCP中用socket套接字实现发送用SeverSocket来接收,在TCP中叫客户端与服务端。

开启顺序

udp开启发送端和服务端顺序无所谓
TCP要先开启服务端监听

数据形式

udp使用socketpacket发送数据包
tcp确立通信后通过数据流传输

TCP的通信流程与三次握手

服务端:

  1. 创建Serversocket,并绑定端口号并监听
  2. accept方法获取客户端socket对象,在此进行三次握手,成功后即可通信
  3. 确定连接后,得到输入流,然后从流中拿数据

客户端:

  1. 创建客户端socket对象,设置目的端口和地址
  2. 得到输出流,并向输出流中写入数据

三次握手

在这里插入图片描述
第一次握手:客户端尝试连接服务器,向服务器发送syn包(同步序列编号Synchronize Sequence Numbers),syn=j,客户端进入SYN_SEND状态等待服务器确认

第二次握手:服务器接收客户端syn包并确认(ack=j+1),同时向客户端发送一个SYN包(syn=k),即SYN+ACK包,此时服务器进入SYN_RECV状态

第三次握手:第三次握手:客户端收到服务器的SYN+ACK包,向服务器发送确认包ACK(ack=k+1),此包发送完毕,客户端和服务器进入ESTABLISHED状态,完成三次握手

定睛一看,服务器ServerSocket与客户端socket建立连接的部分其实就是大名鼎鼎的三次握手
在这里插入图片描述

TCP连接客户端与服务端实现

服务端代码

package network;

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

public class TCPServer {
    public static void main(String[] args) {
        System.out.println("server is starting !!!");
        try {
            //1。创建服务端socket
            ServerSocket serverSocket = new ServerSocket(10006);
            //2。获取客户端对象,用accept方法接收。
            Socket clientSocket = serverSocket.accept();
            System.out.println(clientSocket.getLocalAddress().getHostAddress() + " ...connected");
            //3。获取流
            InputStream inputStream = clientSocket.getInputStream();
            //4。拿出流中的数据
            byte[] buf = new byte[1024];
            int len = inputStream.read(buf);
            String string = new String(buf, 0, len);
            System.out.println(string);
            //关闭
            clientSocket.close();
            serverSocket.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

客户端代码

package network;

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

public class TCPClient {
    public static void main(String[] args) {
        System.out.println("Client start!!!!!");
        try {
            //1. 创建客户端对象,设置目的端口和地址
            Socket s = new Socket("127.0.0.1", 10006);
            //2。 获取socket流中的输出流。
            OutputStream outputStream = s.getOutputStream();
            //3. 将数据放到输出流中。
            outputStream.write("tcp is coming".getBytes());
            //4. 关闭资源
            s.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

在这里插入图片描述

客户端发送给服务器并读取反馈数据

package network;

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

public class TCPechoClient {
    public static void main(String[] args) {
        try {
            Socket clientSocket = new Socket("127.0.0.1", 10006);
            OutputStream outputStream = clientSocket.getOutputStream();
            outputStream.write("Client is coming!!!".getBytes());

            InputStream inputStream = clientSocket.getInputStream();
            byte[] buf = new byte[1024];

            int len = inputStream.read(buf);
            String str = new String(buf, 0, len);
            System.out.println(str);
        } catch (Exception e) {

        }

    }
}


package network;

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

public class TCPechoServer {
    public static void main(String[] args) {
        try {
            ServerSocket serverSocket = new ServerSocket(10006);
            Socket clients = serverSocket.accept();

            InputStream inputStream = clients.getInputStream();
            byte[] buf = new byte[1024];

            int len = inputStream.read(buf);
            String str = new String(buf, 0, len);
            System.out.println(str);

            OutputStream outputStream = clients.getOutputStream();
            outputStream.write("哦了".getBytes());

            clients.close();
        } catch (Exception e) {

        }
    }
}

总结

服务器底层技术:

  1. Serversocket
  2. IO流
  3. 多线程

当服务器接到一个客户端的请求,就可以开一个线程来处理,这样就是开启多线程,主线程负责接收请求并为到来的请求开启单独线程,而单独线程负责执行任务。Tomcat服务器就是这样来实现的。

发布了103 篇原创文章 · 获赞 94 · 访问量 14万+

猜你喜欢

转载自blog.csdn.net/chongbin007/article/details/96604201