TCP通信

文章介绍了如何使用Java实现TCP连接,包括客户端发送消息和服务器接收消息的代码示例。客户端通过Socket指定服务器IP和端口,创建输出流发送数据;服务器通过ServerSocket监听特定端口,接收并处理客户端消息。此外,还展示了TCP文件传输的实现,客户端读取文件并发送,服务器接收并保存文件。
摘要由CSDN通过智能技术生成

TCP


传输控制协议(TCP)是一种面向连接的、可靠的、基于字节流的传输层协议。

在用java实现TCP连接时,我们需要建立服务器与客户端之间的联系,这个联系我们是通过socket,俗称套接字,来实现,接下来我们看一下代码,首先是

客户端代码

import java.io.IOException;
import java.io.OutputStream;
import java.net.InetAddress;
import java.net.Socket;
​
public class TCPCLient {
    public static void main(String[] args) {
        Socket socket=null;
        OutputStream os=null;
        try {
            //1.我得知道一个地址,端口号
            InetAddress serverIp=InetAddress.getByName("127.0.0.1");
            int port=9999;
            //2.创建一个Socket连接
            socket=new Socket(serverIp,port);
            //3.发送消息 IO流
            os=socket.getOutputStream();
            os.write("你好,欢迎学习TCP".getBytes());
​
        } catch (Exceptione) {
            e.printStackTrace();
        }finally {
            if(os!=null){
                try {
                    os.close();
                } catch (IOExceptione) {
                    e.printStackTrace();
                }
            }
            if(socket!=null){
                try {
                    socket.close();
                } catch (IOExceptione) {
                    e.printStackTrace();
                }
            }
        }
    }
}

一定要记得最后关闭资源,先关闭后面创建的。

TCP客户的端步骤如下:

  • 创建socket类,指明主机号,服务器端口号

  • 创建输出流,向服务器发送消息

  • 关闭资源流

服务器代码

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.ServerSocket;
import java.net.Socket;
​
public class TcpServer {
    public static void main(String[] args) {
        ServerSocket serverSocket=null;
        Socket socket=null;
        InputStream  is=null;
        ByteArrayOutputStream baos=null;
        {
            while(true){
                try {
                    //1.我得有个地址
                    serverSocket=new ServerSocket(9999);
                    //2.等待客户端连接过来
                    socket=serverSocket.accept();
                    //3.读取客户端的消息
                    is=socket.getInputStream();
                /*
                byte[] buffer = new byte[1024];
                int len;
                while((len=is.read(buffer))!=-1){
                    String msg = new String(buffer, 0, len);
                    System.out.println(msg);
                }
                */
                    //管道流
                    baos=new ByteArrayOutputStream();
                    byte[] buffer=newbyte[1024];
                    int len;
                    while((len=is.read(buffer))!=-1){
                        baos.write(buffer,0,len);
                    }
                    System.out.println(baos.toString());
​
                } catch (IOExceptione) {
                    e.printStackTrace();
                }finally {
                    //关闭资源
                    if(baos!=null){
                        try {
                            baos.close();
                        } catch (IOExceptione) {
                            e.printStackTrace();
                        }
                    }
                    if(is!=null){
                        try {
                            is.close();
                        } catch (IOExceptione) {
                            e.printStackTrace();
                        }
                    }
                    if(socket!=null){
                        try {
                            socket.close();
                        } catch (IOExceptione) {
                            e.printStackTrace();
                        }
                    }
                    if(serverSocket!=null){
                        try {
                            serverSocket.close();
                        } catch (IOExceptione) {
                            e.printStackTrace();
                        }
                    }
                }
            }
        }
    }
}

可以看到我们中间用到了管道流来接受资源,也就是ByteArrayOutputStream,其实通过名字我们也可以知道ByteArrayOutputStream是对byte类型数据进行写入的类,并且相当于一个中间缓冲层,将类写入到文件等其他outputStream。它是对字节进行操作,属于内存操作流

TCP服务器的步骤如下:

  • 创建ServerSocket,设置端口号

  • ServerSocket.accept进行监听,等待客户端到来

  • 创建输入流进行接受消息

  • 将收到的消息输出

  • 关闭资源流

tips:需要注意的是,服务器的端口号是我们需要自己设置的,因为在客户端连接的时候,需要连接与客户端相同的端口号,两者必须相同,不然无法通信。
我们在此处设置的ip地址127.0.0.1,是我们本机地址
必须先开启服务器,再开启客户端

TCP文件传输


只要掌握的TCP传输的原理步骤,其他的操作都大同小异,最基本的步骤都是一样的只是在中间加入了一些其他操作,像文件传输,我们只需在客户端加入文件输入流,把文件先读取再输出给服务器,服务器则只需加入文件输出流保存文件即可。

客户端代码:

import java.io.ByteArrayOutputStream;
import java.io.FileInputStream;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.InetAddress;
import java.net.Socket;
​
public class FileTcpClient {
    public static void main(String[] args) {
        try {
            InetAddress id=InetAddress.getByName("127.0.0.1");
            Socket socket=new Socket(id,9999);
            OutputStream os=socket.getOutputStream();
            FileInputStream fis=new FileInputStream("TCP.jpg");
            byte[] buffer=new byte[1024];
            int len;
            while((len=fis.read(buffer))!=-1){
                os.write(buffer,0,len);
            }
            //通知服务器我已经结束 已经传输完了
            socket.shutdownOutput();
            InputStream is=socket.getInputStream();
            ByteArrayOutputStream baos=newByteArrayOutputStream();
            byte[] buffer2=new byte[1024];
            int len2;
            while((len2=is.read(buffer2))!=-1){
                baos.write(buffer2,0,len2);
            }
            System.out.println(baos.toString());
            baos.close();
            is.close();
            fis.close();
            os.close();
            socket.close();
        } catch (Exceptione) {
            e.printStackTrace();
        }
​
    }
}

服务器代码:

import java.io.*;
import java.net.ServerSocket;
import java.net.Socket;
​
public class FileTcpServer {
    public static void main(String[] args) {
        try {
            ServerSocket serverSocket=new ServerSocket(9999);
            Socket socket=serverSocket.accept();
            InputStream is=socket.getInputStream();
            FileOutputStream fos=new FileOutputStream(newFile("MyPhoto.jpg"));
            byte[] buffer=new byte[1024];
            intlen;
            while((len=is.read(buffer))!=-1){
                fos.write(buffer,0,len);
            }
            OutputStream os=socket.getOutputStream();
            os.write("我已经接收完毕,你可以关闭了".getBytes());
            //关闭资源
            os.close();
            fos.close();
            is.close();
            socket.close();
            serverSocket.close();
        } catch (Exceptione) {
            e.printStackTrace();
        }
    }
}

注意到,我们在客户端发送完毕的时候用到了shutdownOutput,调用Socket.shutdownOutput()方法后,客户端输出的数据都将被发送,并加上 TCP 的正常连接终止序列(-1,也就是服务端终止循环的判断条件),这样服务端读取数据时就不会被阻塞了。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值