基于Socket的TCP网络编程

基于Socket的TCP编程

Java语言的基于套接字编程分为服务端编程客户端编程,其通信模型如图所示:
在这里插入图片描述

客户端Socket的工作过程

  1. 创建Socket对象,指明服务器端的ip和端口号。
  2. 获取一个输出流,用于输出数据。
  3. 写出数据的操作。
  4. 资源的关闭。

服务器端ServerSocket的工作过程

  1. 创建服务器端的ServerSocket,指明自己的端口号。
  2. 调用accept()表示接收来自于客户端的socket。
  3. 获取输入流。
  4. 读取输入流中的数据。
  5. 关闭资源。

示例一:客户端发送信息给服务端,服务端将数据显示在控制台上。

    @Test
    public void client(){
        Socket socket = null;
        OutputStream outputStream = null;
        try {
        	// 1. 创建Socket对象,指明服务器端的ip和端口号。
            InetAddress inetAddress = InetAddress.getByName("127.0.0.1");
            socket = new Socket(inetAddress,8088);
            // 2. 获取一个输出流,用于输出数据。
            outputStream = socket.getOutputStream();
            // 3. 写出数据的操作。
            outputStream.write("客户端发送消息".getBytes());
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
        	// 4. 资源的关闭
            if (outputStream != null) {
                try {
                    outputStream.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            try {
                if (socket != null)
                    socket.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }


    }
    @Test
    public void server(){
        ServerSocket serverSocket = null;
        Socket accept = null;
        InputStream inputStream = null;
        InputStreamReader inputStreamReader = null;
        ByteArrayOutputStream byteArrayOutputStream = null;
        try {
        	//1.创建服务器端的ServerSocket,指明自己的端口号
            serverSocket = new ServerSocket(8088);
			//2.调用accept()表示接收来自于客户端的socket
            accept = serverSocket.accept();
			//3.获取输入流
            inputStream = accept.getInputStream();
			//4.读取输入流中的数据
            inputStreamReader = new InputStreamReader(inputStream,"utf-8");

//            //方式一:因为inputStream是字节型输入流,所以使用ByteArrayOutputStream解决乱码问题
//            byteArrayOutputStream = new ByteArrayOutputStream();
//            byte[] buffer = new byte[5];
//            int len;
//            while ((len = inputStream.read(buffer)) != -1){
//                byteArrayOutputStream.write(buffer,0,len);
//
//            }
//            System.out.println(byteArrayOutputStream.toString());

            //方式二:使用转换流inputStreamReader解决乱码问题
            char[] cbuf = new char[5];
            int len;
            while ((len = inputStreamReader.read(cbuf)) != -1){
                String str = new String(cbuf,0,len);
                System.out.print(str);
            }
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
        	//5.关闭资源
            try {
                if (byteArrayOutputStream != null)
                    byteArrayOutputStream.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
            try {
                if (inputStreamReader != null)
                    inputStreamReader.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
            try {
                if (inputStream != null)
                    inputStream.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
            try {
                if (accept != null)
                    accept.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
            try {
                if (serverSocket != null)
                    serverSocket.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

输出结果:
在这里插入图片描述
示例二:客户端发送文件给服务端,服务端将文件保存在本地。

public class TCPTest2 {
    @Test
    public void client(){
        Socket socket = null;
        OutputStream outputStream = null;
        FileInputStream fileInputStream = null;
        BufferedInputStream bufferedInputStream= null;
        try {
            InetAddress inetAddress = InetAddress.getByName("127.0.0.1");

            socket = new Socket(inetAddress,8099);

            outputStream = socket.getOutputStream();

            fileInputStream = new FileInputStream(new File("04.PNG"));

            bufferedInputStream = new BufferedInputStream(fileInputStream);

            byte[] buffer = new byte[10];
            int len;
            while ((len = bufferedInputStream.read(buffer)) != -1){
                outputStream.write(buffer,0,len);
            }
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                if (bufferedInputStream != null)
                    bufferedInputStream.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
            try {
                if (fileInputStream != null)
                    fileInputStream.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
            try {
                if (outputStream != null)
                    outputStream.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
            try {
                if (socket != null)
                    socket.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }


    }

    @Test
    public void server(){
        ServerSocket serverSocket = null;
        Socket accept = null;
        InputStream inputStream = null;
        FileOutputStream fileOutputStream = null;
        BufferedOutputStream bufferedOutputStream = null;
        try {
            serverSocket = new ServerSocket(8099);

            accept = serverSocket.accept();

            inputStream = accept.getInputStream();

            fileOutputStream = new FileOutputStream("08.PNG");

            bufferedOutputStream = new BufferedOutputStream(fileOutputStream);

            byte[] buffer = new byte[10];
            int len;
            while((len = inputStream.read(buffer)) != -1){
                bufferedOutputStream.write(buffer,0,len);
            }
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                if (bufferedOutputStream != null)
                    bufferedOutputStream.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
            try {
                if (fileOutputStream != null)
                    fileOutputStream.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
            try {
                if (inputStream != null)
                    inputStream.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
            try {
                if (accept != null)
                    accept.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
            try {
                if (serverSocket != null)
                    serverSocket.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}

示例三:从客户端发送文件给服务端,服务端保存到本地。并返回“发送成功”给客户端。并关闭相应的连接。

public class TCPTest3 {
    @Test
    public void client(){
        Socket socket = null;
        OutputStream outputStream = null;
        FileInputStream fileInputStream = null;
        BufferedInputStream bufferedInputStream= null;
        InputStream inputStream = null;
        ByteArrayOutputStream byteArrayOutputStream = null;
        try {
            InetAddress inetAddress = InetAddress.getByName("127.0.0.1");

            socket = new Socket(inetAddress,8099);

            outputStream = socket.getOutputStream();

            fileInputStream = new FileInputStream(new File("04.PNG"));

            bufferedInputStream = new BufferedInputStream(fileInputStream);

            byte[] buffer = new byte[10];
            int len;
            while ((len = bufferedInputStream.read(buffer)) != -1){
                outputStream.write(buffer,0,len);
            }
            //关闭数据的输出
            socket.shutdownOutput();

            //接收来自服务器端的反馈
            inputStream = socket.getInputStream();
            byteArrayOutputStream = new ByteArrayOutputStream();
            byte[] buffer1 = new byte[20];
            int len1;
            while ((len = inputStream.read(buffer)) != -1){
                byteArrayOutputStream.write(buffer,0,len);
            }
            System.out.println(byteArrayOutputStream.toString());

        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                if (inputStream != null)
                    inputStream.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
            try {
                if (byteArrayOutputStream != null)
                    byteArrayOutputStream.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
            try {
                if (bufferedInputStream != null)
                    bufferedInputStream.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
            try {
                if (fileInputStream != null)
                    fileInputStream.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
            try {
                if (outputStream != null)
                    outputStream.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
            try {
                if (socket != null)
                    socket.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }


    }

    @Test
    public void server(){
        ServerSocket serverSocket = null;
        Socket accept = null;
        InputStream inputStream = null;
        FileOutputStream fileOutputStream = null;
        BufferedOutputStream bufferedOutputStream = null;
        OutputStream outputStream = null;
        try {
            serverSocket = new ServerSocket(8099);

            accept = serverSocket.accept();

            inputStream = accept.getInputStream();

            fileOutputStream = new FileOutputStream("09.PNG");

            bufferedOutputStream = new BufferedOutputStream(fileOutputStream);

            byte[] buffer = new byte[10];
            int len;
            while((len = inputStream.read(buffer)) != -1){
                bufferedOutputStream.write(buffer,0,len);
            }

            //服务器端接收成功,给予客户端反馈
            outputStream = accept.getOutputStream();
            outputStream.write("数据已接收!".getBytes());

        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                if (outputStream != null)
                    outputStream.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
            try {
                if (bufferedOutputStream != null)
                    bufferedOutputStream.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
            try {
                if (fileOutputStream != null)
                    fileOutputStream.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
            try {
                if (inputStream != null)
                    inputStream.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
            try {
                if (accept != null)
                    accept.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
            try {
                if (serverSocket != null)
                    serverSocket.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: 基于TCP和UDP的socket编程网络编程中常用的两种方式。TCP是面向连接的可靠传输协议,UDP是无连接的不可靠传输协议。 使用TCP协议进行socket编程时,需要先建立连接,然后再进行数据传输。建立连接时,需要使用服务器端的IP地址和端口号来连接服务器。连接建立后,数据传输可以通过套接字进行。TCP协议保证了数据传输的可靠性,但是会影响传输速度。 使用UDP协议进行socket编程时,不需要建立连接,可以直接进行数据传输。数据传输时,需要指定目标地址和端口号。UDP协议没有连接的开销,可以提高传输速度,但是传输过程中可能会发生数据包丢失或乱序。 无论是基于TCP还是UDP的socket编程,都需要使用socket函数来创建套接字,然后通过bind函数绑定IP地址和端口号,最后通过send和recv函数进行数据传输。 ### 回答2: Socket(套接字)编程是指利用套接字来实现网络通信的编程技术。套接字是一种通信机制,应用程序通过套接字向网络发出请求,然后接收网络的响应。常用的套接字类型有基于TCP传输控制协议)和UDP(用户数据报协议)两种,下面将分别介绍基于TCP和UDP的Socket编程。 1. 基于TCPSocket编程 TCP是一种面向连接的协议,在进行数据传输之前必须先建立连接,然后才能进行数据传输TCP协议通过三次握手建立连接,保证数据可靠传输。基于TCPSocket编程主要流程如下: (1)创建Socket套接字。 (2)绑定Socket到本地地址和端口。 (3)监听连接请求,等待客户端连接。 (4)接受客户端连接请求,建立TCP连接。 (5)发送和接收数据。 (6)关闭Socket,释放资源。 在TCP协议中,客户端和服务端之间都需要建立连接,因此在建立连接之前需要先创建Socket套接字,指定本地地址和端口。然后服务端通过listen函数监听连接请求,等待客户端连接。客户端连接成功后,服务端accept函数接收连接请求,建立TCP连接。连接建立后,客户端和服务端可以通过send和recv函数进行数据传输传输结束后,需要通过close函数关闭连接,释放资源。 TCP协议主要特点是安全可靠,传输速度较慢。因此TCP协议适用于数据传输要求高可靠性的场景,如文件传输、电子邮件等。 2. 基于UDP的Socket编程 UDP是一种无连接的协议,数据传输时不需要建立连接,发送端发送数据后,接收端直接收到数据。虽然UDP传输速度快,但数据传输并不可靠,可能丢失数据或出现乱序。基于UDP的Socket编程主要流程如下: (1)创建Socket套接字。 (2)绑定Socket到本地地址和端口。 (3)发送数据。 (4)接收数据。 (5)关闭Socket,释放资源。 UDP协议主要特点是速度快、传输不可靠。因此UDP适用于实时性要求高、数据可靠性要求不高的场景,如网络游戏、实时视频等。 总之,基于TCP和UDP的Socket编程网络编程中常用的技术,应用广泛。在实际开发中,要根据实际需求选择合适的协议,保证数据传输的可靠性和效率。 ### 回答3: Socket编程是一项网络编程技术,它允许程序员使用TCP/IP协议来进行通信。Socket通常与网络编程、Web开发相关。计算机的应用程序间通过Socket传输数据,Socket是应用程序和传输层协议之间的接口,通常使用TCP/IP协议进行网络通信。 TCP传输控制协议)提供了端到端的可靠数据传输服务,它基于连接进行通信,确保数据不会丢失或损坏,并且按照发送顺序到达接收方。TCP通过三次握手建立连接,然后进行数据传输,最后断开连接。在Socket编程中,如果要使用TCP协议,则必须创建一个TCP套接字。TCP套接字可以用于客户端或服务器端,服务器端必须先创建套接字并等待客户端的连接请求,客户端则通过TCP连接到服务器。在连接成功后,双方可以交换数据,结束时断开连接。 UDP(用户数据报协议)是无连接的,不可靠的数据传输服务,在数据传输过程中可能会丢失一定量的数据,但它具有高效性、实时性和简单性。UDP套接字不需要建立连接,直接发送数据报到目的地。在Socket编程中,如果要使用UDP协议,则必须创建一个UDP套接字,可以用于客户端或服务器端。UDP允许发送数据报到一个多播地址,这意味着可以一次向多个客户端发送数据。 在Socket编程中,使用TCP和UDP协议需要注意以下几点: 1. 建立TCP连接时要进行三次握手,结束时要进行四次挥手,这会增加一些延迟和开销;而建立UDP连接不需要握手和挥手,速度更快。 2. TCP保证数据不会丢失或损坏,而UDP可能会丢失一些数据,因此需要在应用程序中进行数据包的重新传输和处理。 3. 在Socket编程中,应尽可能使用可重用的套接字,以免出现套接字资源短缺的问题。 4. 应尽可能使用异步I/O编程,以避免阻塞线程。在异步I/O模式中,应用程序可以发出I/O请求并继续执行其他操作,当操作完成时,操作系统会通知应用程序进行下一步处理。这种方式比同步I/O编程更高效,并且可以实现更高的并发性。 总之,TCP和UDP是Socket编程中最常用的协议,它们各自具有优缺点,应根据应用程序的需求选择合适的协议。在使用Socket编程时,应尽可能考虑性能、可靠性和安全性等问题,以保证应用程序的稳定和可靠。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值