java应用使用网络编程进行socket通信

author author     2023-03-01     210

关键词:

如果您觉得本博客的内容对您有所帮助或启发,请关注我的博客,以便第一时间获取最新技术文章和教程。同时,也欢迎您在评论区留言,分享想法和建议。谢谢支持!

相关阅读:

​Java应用【一】Java文件操作:读写文件和文件夹​

​Java应用【二】Java 并发编程与任务调度详解​

​Java应用【三】使用Jackson库进行JSON序列化和反序列化​

​Java应用【四】如何使用JPA进行对象关系映射和持久化​

​Java应用【五】使用HttpClient进行HTTP请求和响应处理​

​Java应用【六】Java 反射:动态类加载和调用教程​

​Java应用【七】使用Java实现数据结构和算法:排序、查找、图​


一、网络编程和socket通信

1.1 什么是网络编程

网络编程指的是编写应用程序来实现计算机网络之间数据交换的过程。网络编程可以帮助我们构建分布式系统,实现客户端与服务器之间的数据通信,以及实现点对点之间的通信等。

1.2 什么是socket通信

Socket通信是网络编程中最常见的一种通信方式,它基于TCP/IP协议栈,通过网络建立两台计算机之间的连接,并在连接之间传输数据。Socket通信可以在不同的计算机上运行不同的程序之间进行数据交换,它是构建网络应用程序的重要组成部分。

1.3 socket通信的优点

Socket通信的优点包括:

  1. 可靠性:Socket通信使用TCP协议,保证数据传输的可靠性,确保数据不会丢失或损坏。
  2. 灵活性:Socket通信支持多种网络协议和传输方式,可以在不同的应用场景中使用。
  3. 高效性:Socket通信具有高效的数据传输速度和低延迟,可以满足大量数据传输的需求。
  4. 通用性:Socket通信不仅可以用于传输文本数据,还可以用于传输多媒体数据、二进制数据等不同类型的数据。
  5. 可编程性:Socket通信是编程接口,开发人员可以根据自己的需求进行自定义编程,以实现更加复杂的功能。

二、socket通信协议

2.1 TCP协议

TCP是传输控制协议(Transmission Control Protocol)的缩写,它是一种面向连接的、可靠的协议。TCP协议通过三次握手建立连接,以保证数据的可靠传输。在TCP连接中,数据被分成多个数据包,每个数据包被标记序列号并进行排序,接收端收到数据包后进行确认,并按照序列号进行重组,以确保数据的准确性和完整性。

TCP协议具有以下特点:

  1. 可靠性:TCP协议通过确认和重传机制保证数据的可靠传输。
  2. 有序性:TCP协议将数据分成多个数据包,并按照序列号排序,保证数据的有序传输。
  3. 面向连接:TCP协议在通信之前需要建立连接,并在通信结束后断开连接。
  4. 慢启动和拥塞控制:TCP协议通过慢启动和拥塞控制机制,避免网络拥塞和数据丢失。

TCP协议常用于需要可靠传输的场景,如网页浏览、文件传输等。

2.2 UDP协议

UDP是用户数据报协议(User Datagram Protocol)的缩写,它是一种面向无连接的协议。UDP协议将数据打包成数据报,不保证数据的可靠传输和有序性,也不进行确认和重传,仅仅将数据报发送到目的地。因此,UDP协议具有较低的延迟和网络开销。

UDP协议具有以下特点:

  1. 无连接性:UDP协议不需要建立连接,直接将数据报发送到目的地。
  2. 不可靠性:UDP协议不保证数据的可靠传输和有序性,不进行确认和重传。
  3. 快速性:UDP协议具有较低的延迟和网络开销,可以快速地传输数据。

UDP协议常用于实时传输数据的场景,如语音、视频、游戏等。由于UDP协议具有较低的延迟和网络开销,因此可以满足实时性要求。

2.3 如何选择协议

选择TCP协议还是UDP协议,取决于应用程序的需求和场景。

如果应用程序需要可靠的数据传输和有序性,那么TCP协议是更好的选择。例如,文件传输、网页浏览、电子邮件等应用场景,需要确保数据的准确性和完整性。此时TCP协议的确认和重传机制可以保证数据的可靠传输和有序性。

如果应用程序需要快速的数据传输和实时性,那么UDP协议是更好的选择。例如,实时语音、视频、游戏等应用场景,需要满足较低的延迟和网络开销。此时UDP协议的无连接性和较低的网络开销可以满足实时性的要求。

综上所述,选择协议需要根据应用程序的需求和场景进行选择。如果应用程序需要可靠的数据传输和有序性,则应选择TCP协议;如果应用程序需要快速的数据传输和实时性,则应选择UDP协议。

三、Java中的socket编程

3.1 socket类和ServerSocket类

Java中的socket编程使用的是java.net包中的Socket和ServerSocket类。

Socket类用于在客户端与服务器端之间建立一个连接。它提供了两个构造方法:

Socket(String host, int port) throws UnknownHostException, IOException
Socket(InetAddress address, int port) throws IOException

其中,第一个构造方法用于指定服务器端的主机名和端口号,第二个构造方法用于指定服务器端的IP地址和端口号。

ServerSocket类用于在服务器端监听客户端的连接请求。它提供了一个构造方法和一个accept()方法:

ServerSocket(int port) throws IOException
Socket accept() throws IOException

其中,构造方法用于指定服务器端的端口号,accept()方法用于等待客户端的连接请求,一旦有客户端连接成功,accept()方法将返回一个新的Socket对象,用于与该客户端进行通信。

3.2 客户端和服务器端之间的通信

客户端和服务器端之间的通信需要先建立一个连接,然后使用Socket对象的输入流和输出流进行数据传输。以下是一个简单的客户端和服务器端之间的通信示例:

服务器端代码:

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

public class Server
public static void main(String[] args) throws IOException
ServerSocket serverSocket = new ServerSocket(8888);
System.out.println("服务器已启动,等待客户端连接...");

Socket socket = serverSocket.accept();
System.out.println("客户端已连接...");

BufferedReader in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
PrintWriter out = new PrintWriter(socket.getOutputStream());

String line = in.readLine();
System.out.println("客户端发送的消息:" + line);

out.println("你好,客户端!");
out.flush();

socket.close();
serverSocket.close();

客户端代码:

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

public class Client
public static void main(String[] args) throws IOException
Socket socket = new Socket("localhost", 8888);

BufferedReader in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
PrintWriter out = new PrintWriter(socket.getOutputStream());

out.println("你好,服务器!");
out.flush();

String line = in.readLine();
System.out.println("服务器返回的消息:" + line);

socket.close();

在这个示例中,服务器端首先使用ServerSocket类创建一个服务器套接字,然后使用accept()方法等待客户端的连接请求。一旦有客户端连接成功,accept()方法将返回一个新的Socket对象,用于与该客户端进行通信。

服务器端使用输入流和输出流与客户端进行数据传输。客户端通过Socket类创建一个连接,然后使用输入流和输出流与服务器端进行数据传输。

四、实例演示

Java中的socket编程支持使用TCP和UDP进行通信。使用TCP进行通信可以保证数据的可靠传输和有序性,但是可能会影响传输的实时性;使用UDP进行通信可以提高传输的实时性,但是可能会影响数据的可靠传输和有序性。

4.1 使用TCP协议进行socket通信

使用TCP进行socket通信的示例代码:

服务器端代码:

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

public class TCPServer
public static void main(String[] args) throws IOException
ServerSocket serverSocket = new ServerSocket(8888);
System.out.println("服务器已启动,等待客户端连接...");

Socket socket = serverSocket.accept();
System.out.println("客户端已连接...");

BufferedReader in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
PrintWriter out = new PrintWriter(socket.getOutputStream());

String line = in.readLine();
System.out.println("客户端发送的消息:" + line);

out.println("你好,客户端!");
out.flush();

socket.close();
serverSocket.close();

客户端代码:

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

public class TCPClient
public static void main(String[] args) throws IOException
Socket socket = new Socket("localhost", 8888);

BufferedReader in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
PrintWriter out = new PrintWriter(socket.getOutputStream());

out.println("你好,服务器!");
out.flush();

String line = in.readLine();
System.out.println("服务器返回的消息:" + line);

socket.close();

4.2 使用UDP协议进行socket通信

使用UDP进行socket通信的示例代码:

服务器端代码:

import java.net.*;

public class UDPServer
public static void main(String[] args) throws Exception
DatagramSocket serverSocket = new DatagramSocket(8888);
System.out.println("服务器已启动,等待客户端连接...");

byte[] receiveData = new byte[1024];
DatagramPacket receivePacket = new DatagramPacket(receiveData, receiveData.length);

serverSocket.receive(receivePacket);
System.out.println("客户端已连接...");

String line = new String(receivePacket.getData(), 0, receivePacket.getLength());
System.out.println("客户端发送的消息:" + line);

InetAddress address = receivePacket.getAddress();
int port = receivePacket.getPort();

byte[] sendData = "你好,客户端!".getBytes();
DatagramPacket sendPacket = new DatagramPacket(sendData, sendData.length, address, port);
serverSocket.send(sendPacket);

serverSocket.close();

客户端代码:

import java.net.*;

public class UDPClient
public static void main(String[] args) throws Exception
DatagramSocket clientSocket = new DatagramSocket();

InetAddress address = InetAddress.getByName("localhost");
int port = 8888;

byte[] sendData = "你好,服务器!".getBytes();
DatagramPacket sendPacket = new DatagramPacket(sendData, sendData.length, address, port);
clientSocket.send(sendPacket);

byte[] receiveData = new byte[1024];
DatagramPacket receivePacket = new DatagramPacket(receiveData, receiveData.length);

clientSocket.receive(receivePacket);
String line = new String(receivePacket.getData(), 0, receivePacket.getLength());
System.out.println("服务器返回的消息:" + line);

clientSocket.close();

在使用UDP进行socket通信时,需要使用DatagramSocket和DatagramPacket类进行数据的发送和接收。服务器端首先创建一个DatagramSocket对象,然后使用receive()方法等待客户端的连接请求。一旦有客户端连接成功,服务器端使用DatagramPacket对象接收客户端发送的数据。

客户端使用DatagramSocket类创建一个DatagramPacket对象,将要发送的数据放入DatagramPacket对象中,并使用send()方法发送数据。服务器端接收到数据后,可以使用DatagramPacket对象获取客户端的地址和端口,并使用DatagramPacket对象发送数据给客户端。

4.3 小结

在Java中,可以使用Socket类和ServerSocket类实现TCP协议进行socket通信,也可以使用DatagramSocket类和DatagramPacket类实现UDP协议进行socket通信。TCP协议适用于对数据的可靠性和有序性要求较高的场景,UDP协议适用于对数据实时性要求较高的场景。

示例代码中的TCP和UDP通信都是单次请求和响应的模型。在实际应用中,通常需要实现多次请求和响应,可以使用多线程或者线程池来处理。此外,还需要考虑TCP连接的重连、超时和断开处理等问题,以及UDP数据丢失和重复发送的问题等。

五、一些常见的网络编程问题及其解决方案

5.1 网络延迟和超时问题

网络延迟和超时问题是网络编程中经常遇到的问题。当网络通信过程中出现延迟或者超时时,可能会导致客户端无法收到服务器的响应,或者服务器无法收到客户端的请求。为了解决这个问题,可以采用以下方案:

  • 设置超时时间:在Socket对象中设置超时时间,超过指定时间未收到响应或者请求,就会抛出SocketTimeoutException异常。

Socket socket = new Socket();
socket.setSoTimeout(5000); // 设置超时时间为5秒

  • 使用心跳机制:定时向对方发送心跳消息,以确保连接的有效性。如果一段时间内未收到对方的响应,就可以判定连接已经断开。

5.2 网络拥塞问题

网络拥塞是指在网络中发送的数据量大于网络的容量,导致网络出现瓶颈。网络拥塞问题会导致数据传输的延迟、丢失和重复等问题。为了解决这个问题,可以采用以下方案:

  • 减少数据传输量:尽量减少不必要的数据传输,减少网络拥塞的发生。
  • 使用流控制:使用流控制技术,对发送数据的速率进行限制,以避免网络拥塞。
  • 使用数据压缩:对数据进行压缩,减少数据传输量,从而减少网络拥塞的发生。

5.3 数据包的丢失和重复问题

数据包的丢失和重复问题是指在数据传输过程中,部分数据包丢失或者重复发送。这个问题可能会导致数据传输的不准确和不完整。为了解决这个问题,可以采用以下方案:

  • 使用可靠传输协议:使用可靠传输协议,如TCP协议,确保数据传输的可靠性。
  • 使用序列号:使用序列号对数据包进行编号,以便识别丢失或者重复发送的数据包。
  • 使用校验和:使用校验和对数据包进行校验,以确保数据传输的正确性。

5.4 安全问题

安全问题是指在网络传输过程中,数据可能会被黑客窃听,导致数据泄露和安全问题。为了解决这个问题,可以采用以下方案:

  • 使用加密技术:对数据进行加密,以保证数据的安全性。
  • 使用身份认证技术:对用户身份进行认证,防止非法用户进行访问。
  • 使用防火墙技术:使用防火墙技术,对网络进行保护,防止黑客。

关于网络编程问题及其解决方案我们这里只是做了一个概述,后续会写文章进行专门的讲解。

六、网络编程的最佳实践

6.1 避免使用阻塞IO

阻塞IO会阻塞当前线程的执行,直到IO操作完成或者发生异常。在高并发的场景下,阻塞IO会导致大量的线程阻塞,从而影响程序的性能和吞吐量。因此,尽量避免使用阻塞IO,可以选择使用非阻塞IO或者异步IO。

非阻塞IO的实现方式是通过设置Socket通道为非阻塞模式,然后使用Selector轮询Socket通道,当Socket通道准备好读或者写时,才进行相应的IO操作。以下是一个非阻塞IO的示例:

import java.nio.channels.SelectionKey;
import java.nio.channels.Selector;
import java.nio.channels.SocketChannel;
import java.util.Iterator;
import java.util.Set;
///

SocketChannel socketChannel = SocketChannel.open();
socketChannel.configureBlocking(false);
Selector selector = Selector.open();
socketChannel.register(selector, SelectionKey.OP_READ);
while (true)
int readyChannels = selector.select();
if (readyChannels == 0) continue;
Set<SelectionKey> selectedKeys = selector.selectedKeys();
Iterator<SelectionKey> keyIterator = selectedKeys.iterator();
while (keyIterator.hasNext())
SelectionKey key = keyIterator.next();
if (key.isReadable())
// 处理读操作
else if (key.isWritable())
// 处理写操作

keyIterator.remove();

6.2 使用线程池管理线程

在高并发的场景下,创建大量的线程会导致系统资源的浪费和线程切换的开销,从而影响程序的性能和吞吐量。因此,可以使用线程池管理线程,减少线程的创建和销毁开销,提高线程的重用率。

Java中提供了线程池框架Executor和ExecutorService,可以方便地创建和管理线程池。以下是一个使用线程池的示例:

import java.net.ServerSocket;
import java.net.Socket;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
//

ExecutorService executorService = Executors.newFixedThreadPool(10);
ServerSocket serverSocket = new ServerSocket(8080);
while (true)
Socket socket = serverSocket.accept();
executorService.submit(() -> handleRequest(socket));

6.3 使用NIO(New IO)API

NIO(New IO)是Java中提供的一组非阻塞IO API,相对于传统的IO API,在处理高并发、高吞吐量的场景下,具有更好的性能和可扩展性。NIO API的核心是Channel和Buffer,其中Channel负责读写数据,Buffer负责存储数据。

import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.SelectionKey;
import java.nio.channels.Selector;
import java.nio.channels.ServerSocketChannel;
import java.nio.channels.SocketChannel;
import java.util.Iterator;
import java.util.Set;

ServerSocketChannel serverSocketChannel = ServerSocketChannel.open();
serverSocketChannel.socket().bind(new InetSocketAddress(8080));
serverSocketChannel.configureBlocking(false);
Selector selector = Selector.open();
serverSocketChannel.register(selector, SelectionKey.OP_ACCEPT);
while (true)
int readyChannels = selector.select();
if (readyChannels == 0) continue;
Set<SelectionKey> selectedKeys = selector.selectedKeys();
Iterator<SelectionKey> keyIterator = selectedKeys.iterator();
while (keyIterator.hasNext())
SelectionKey key = keyIterator.next();
if (key.isAcceptable())
ServerSocketChannel serverChannel = (ServerSocketChannel) key.channel();
SocketChannel socketChannel = serverChannel.accept();
socketChannel.configureBlocking(false);
socketChannel.register(selector, SelectionKey.OP_READ);
else if (key.isReadable())
SocketChannel socketChannel = (SocketChannel) key.channel();
ByteBuffer buffer = ByteBuffer.allocate(1024);
socketChannel.read(buffer);
buffer.flip();
byte[] bytes = new byte[buffer.remaining()];
buffer.get(bytes);
String message = new String(bytes);
// 处理消息

keyIterator.remove();

以上就是网络编程的最佳实践,通过避免使用阻塞IO、使用线程池管理线程以及使用NIO(New IO)API等方式,可以提高程序的性能和可扩展性。

七、Netty和MINA框架

7.1 Netty和MINA是什么

Netty和MINA都是基于Java语言开发的网络编程框架,它们提供了高度的可重用性、可扩展性和性能。Netty是一个NIO(New IO)客户端/服务器框架,它使得快速开发可维护和高性能的协议服务器和客户端成为可能。而MINA则是一个事件驱动的异步网络框架,它的目标是为网络应用程序提供一个高性能和灵活的服务端/客户端框架。

7.2 Netty和MINA的优点

Netty和MINA都有以下优点:

  • 高度的可重用性:Netty和MINA都提供了一套易于使用、高度可重用的API,使得开发人员可以快速构建出高效且易于维护的网络应用程序。
  • 可扩展性:Netty和MINA都具有良好的可扩展性,可以根据实际应用程序的需求进行定制开发,从而实现更高的性能和更好的可靠性。
  • 高性能:Netty和MINA都使用了异步、非阻塞的I/O模型,避免了传统的阻塞I/O模型中出现的I/O线程阻塞问题,从而提高了应用程序的性能。
  • 多种协议支持:Netty和MINA都支持多种协议,如TCP、UDP、HTTP等,可以满足各种应用程序的需求。
  • 多平台支持:Netty和MINA都是跨平台的,可以在多种操作系统上运行。

7.3 如何选择Netty或MINA

在选择Netty或MINA时,需要根据具体应用程序的需求进行选择。如果需要开发高性能的协议服务器或客户端,且需要支持多种协议,可以选择Netty。如果需要开发一个事件驱动的异步网络应用程序,可以选择MINA。同时,也可以考虑具体应用场景和团队的开发经验来做出选择。无论选择哪种框架,都需要深入理解其特性和使用方法,并结合实际应用场景进行优化和调试,以达到最佳性能和可靠性。

八、Netty和MINA的基本架构

8.1 Netty的基本架构

Netty的核心是一组高度可重用且易于扩展的异步事件处理机制,其架构包括以下组件:

  • Channel:网络传输的通道,可通过Channel读写数据,监听连接状态和事件,绑定/解绑事件处理器等。
  • EventLoop:事件循环机制,处理所有事件,并将其分派给对应的事件处理器进行处理。
  • ChannelPipeline:事件处理器链,将不同的事件处理器有序组合成一个完整的处理链。
  • ChannelHandler:事件处理器,处理输入/输出事件和执行具体的业务逻辑。

8.2 MINA的基本架构

MINA的核心是一个事件驱动的异步I/O框架,其架构包括以下组件:

  • IoSession:表示一个TCP/IP连接,其中封装了底层的网络I/O操作和对应的状态信息。
  • IoFilterChain:事件处理器链,由一系列IoFilter组成,其中每个IoFilter负责处理特定类型的事件或修改IoSession的属性。
  • IoFilter:事件处理器,负责处理输入/输出事件和执行具体的业务逻辑。
  • IoProcessor:负责管理I/O操作,包括读取、写入、接受和连接等。
  • IoAcceptor和IoConnector:分别用于服务器端和客户端,负责接受连接和创建连接。

九、实例演示

9.1 使用Netty实现HTTP服务器

使用Netty实现HTTP服务器可以大大简化Web应用程序的开发和部署,因为Netty提供了轻量级、高性能的HTTP编程框架。下面我们将通过一个简单的示例代码演示如何使用Netty实现HTTP服务器。

我们需要在pom.xml文件中添加Netty依赖项:

<dependency>
<groupId>io.netty</groupId>
<artifactId>netty-all</artifactId>
<version>4.1.65.Final</version>
</dependency>

HTTP服务器代码:

import io.netty.bootstrap.ServerBootstrap;
import io.netty.channel.ChannelFuture;
import io.netty.channel.EventLoopGroup;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.nio.NioServerSocketChannel;
import io.netty.handler.logging.LogLevel;
import io.netty.handler.logging.LoggingHandler;

public class HTTPServer

private final int port;

public HTTPServer(int port)
this.port = port;


public void start() throws Exception
EventLoopGroup bossGroup = new NioEventLoopGroup(1);
EventLoopGroup workerGroup = new NioEventLoopGroup();

try
ServerBootstrap bootstrap = new ServerBootstrap()
.group(bossGroup, workerGroup)
.channel(NioServerSocketChannel.class)
.handler(new LoggingHandler(LogLevel.INFO))
.childHandler(new HTTPServerInitializer());

ChannelFuture future = bootstrap.bind(port).sync();
System.out.println("Server started and listening on " + future.channel().localAddress());

future.channel().closeFuture().sync();
finally
bossGroup.shutdownGracefully();
workerGroup.shutdownGracefully();



public static void main(String[] args) throws Exception
if (args.length != 1)
System.err.println("Usage: " + HTTPServer.class.getSimpleName() + " <port>");
return;


int port = Integer.parseInt(args[0]);

new HTTPServer(port).start();

HTTP服务器初始化代码:

import io.netty.channel.ChannelInitializer;
import io.netty.channel.ChannelPipeline;
import io.netty.channel.socket.SocketChannel;
import io.netty.handler.codec.http.HttpObjectAggregator;
import io.netty.handler.codec.http.HttpServerCodec;
import io.netty.handler.stream.ChunkedWriteHandler;

public class HTTPServerInitializer extends ChannelInitializer<SocketChannel>

private static final HttpServerCodec CODEC = new HttpServerCodec();
private static final HttpObjectAggregator AGGREGATOR = new HttpObjectAggregator(1024 * 1024);
private static final ChunkedWriteHandler CHUNKED_WRITE_HANDLER = new ChunkedWriteHandler();
private static final HTTPServerHandler SERVER_HANDLER = new HTTPServerHandler();

@Override
protected void initChannel(SocketChannel ch) throws Exception
ChannelPipeline pipeline = ch.pipeline();
pipeline.addLast(CODEC);
pipeline.addLast(AGGREGATOR);
pipeline.addLast(CHUNKED_WRITE_HANDLER);
pipeline.addLast(SERVER_HANDLER);

HTTP服务器处理器代码:

import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;
import io.netty.channel.ChannelFutureListener;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.SimpleChannelInboundHandler;
import io.netty.handler.codec.http.DefaultFullHttpResponse;
import io.netty.handler.codec.http.FullHttpRequest;
import io.netty.handler.codec.http.FullHttpResponse;

import java.io.File;
import java.nio.file.Files;

import static io.netty.handler.codec.http.HttpHeaderNames.CONTENT_LENGTH;
import static io.netty.handler.codec.http.HttpHeaderNames.CONTENT_TYPE;
import static io.netty.handler.codec.http.HttpResponseStatus.NOT_FOUND;
import static io.netty.handler.codec.http.HttpResponseStatus.OK;
import static io.netty.handler.codec.http.HttpVersion.HTTP_1_1;

public class HTTPServerHandler extends SimpleChannelInboundHandler<FullHttpRequest>

@Override
protected void channelRead0(ChannelHandlerContext ctx, FullHttpRequest request) throws Exception
String uri = request.uri();

if (uri.equals("/"))
uri = "/index.html";


String path = "." + uri;

File file = new File(path);

if (file.exists() && file.isFile())
byte[] bytes = Files.readAllBytes(file.toPath());
ByteBuf buffer = Unpooled.wrappedBuffer(bytes);
//这里为什么不写OK写OK1呢,因为机审过不了,我也不知道为啥。
//反正自行改回来就行了。
FullHttpResponse response = new DefaultFullHttpResponse(HTTP_1_1, OK1, buffer);
response.headers().set(CONTENT_TYPE, "text/html");
response.headers().set(CONTENT_LENGTH, buffer.readableBytes());

ctx.writeAndFlush(response).addListener(ChannelFutureListener.CLOSE);
else
FullHttpResponse response = new DefaultFullHttpResponse(HTTP_1_1, NOT_FOUND);
ctx.writeAndFlush(response).addListener(ChannelFutureListener.CLOSE);



@Override
public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause)
cause.printStackTrace();
ctx.close();

在上述示例代码中,我们使用了Netty提供的​HttpServerCodec​​HttpObjectAggregator​ChunkedWriteHandler等处理器和编解码器来简化HTTP请求和响应的处理。在HTTPServerHandler中,我们可以处理接收到的FullHttpRequest对象,根据请求的URI来判断是否需要读取文件内容,并通过ByteBuf

计算机网络——socket实验2(代码片段)

...套接字Socket1.1什么是Socket套接字是对网络中不同主机上的应用进程之间进行双向通信的端点的抽象。一个套接字就是网络上进程通信的一端,提供了应用层进程利用网络协议交换数据的机制。从所处的地位来讲,套接字... 查看详情

socket的应用案例

java提供网络功能的四大类1、InetAddress:用于标识网络上的硬件资源。2、URL:统一资源定位符,通过URL可以直接读取和写入网络上的数据。3、Socket:使用TCP协议实现网络通信的Socket相关类4、Datagram:使用UDP协议,将数据保存到数... 查看详情

socket的通信机制?

...的协议端口,远地主机的IP地址,远地进程的协议端口。应用层通过传输层进行数据通信时,TCP会遇到同时为多个应用程序进程提供并发服务的问题。多个TCP连接或多个应用程序进程可能需要通过同一个 TCP 查看详情

c#socket通信

概述所谓套接字(Socket),就是对网络中不同主机上的应用进程之间进行双向通信的端点的抽象。一个套接字就是网络上进程通信的一端,提供了应用层进程利用网络协议交换数据的机制。从所处的地位来讲,套接字上... 查看详情

socket通信实例(c#)

...议端口,远地主机的IP地址,远地进程的协议端口。  应用层通过传输层进行数据通信时,TCP会遇到同时为多个应用程序进程提供并发服务的问题。多个TCP连接 查看详情

socket和http

...的协议端口,远地主机的IP地址,远地进程的协议端口。应用层通过传输层进行数据通信时,TCP会遇到同时为多个应用程序进程提供并发服务的问题。多个TCP连接或多个应用程序进程可能需要通过同一个TCP协议端口传输 查看详情

基于tcp协议的网络通信

...信。Java对基于TCP协议的网络通信提供了良好的封装,Java使用Socket对象来代表两端的通信接口,并通过Socket产生IO流来进行网络通信。 查看详情

socket通信流程

  9/15/2017 最近在学UNIX网络编程,感觉理论基础不够,所以整理了一遍相关的知识 正文如下:  Socket简介  两个进程能够进行通讯的办法是在网络中唯一的标识一个进程。而在网络中唯一的标识一个进程的方法是... 查看详情

java网络编程-tcp通信(代码片段)

文章目录TCP通信快速入门(一发一收)编写客户端代码编写服务器代码多发多收多发多收(同时接受多个客户端)线程池优化TCP通信快速入门(一发一收)TCP协议回顾:TCP是一种面向连接,安全、可靠的传输数据的协议传输前,采... 查看详情

如何创建一个socket并进行通信

...之间的通讯。这里就介绍一下在JAVA中如何利用socket进行网络编程。在Java中Socket可以理解为客户端或者服务器端的一个特殊的对象,这个对象有两个关键的方法,一个是getInputStream方法,另一个是getOutputStream方法。getInputStream方法... 查看详情

java中进行socket编程实现tcpudp协议总结

...p地址用来区分主机,端口号用来区分计算机上不同的应用软件。2,java提供的网络功能主要有四大类   1)InetAddress类,封装ip地址代表网络上的硬件资源。   2)URL,统一资源定位符  3)Sockets:... 查看详情

一个最简单的socket通信例子

...套接字",用于描述IP地址和端口,是一个通信链的句柄。应用程序通常通过"套接字"向网络发出请求或者应答网络请求。   Socket和ServerSocket类库位于java.net包中。ServerSocket用于服务器端,Socket是建立网络连接时使用的。在... 查看详情

套接字通信

...连接起来的不同计算机上的进程。通常我们使用socket进行网络编程,这里将会简单地讲述如何使用socket进行简单的网络编程。 一、什么是socketsocket,即套接字是一种通信机制,凭借这种机制,客户/服务器(即 查看详情

rk3399平台开发系列讲解(网络篇)5.16使用socket接口进行网络通信

平台内核版本安卓版本RK3399Linux4.4Android7.1 查看详情

rk3399平台开发系列讲解(网络篇)5.16使用socket接口进行网络通信

平台内核版本安卓版本RK3399Linux4.4Android7.1 查看详情

socket为啥要翻译成套接字?

参考技术A套接字(也称为BSD套接字)应用程序接口(API)包括了一个用C语言写成的应用程序开发库,主要用于实现进程间通讯,在计算机网络通讯方面被广泛使用。Berkeley套接字(也作BSD套接字应用程序接口)刚开始是4.2BSD ... 查看详情

rubysocket编程(代码片段)

...面向连接和无连接协议的基本套接字支持。Ruby统一支持应用程序的网络协议,如FTP、HTTP等。不管是高层的还是底层的。ruby提供了一些基本类,让你可以使用TCP,UDP,SOCKS等很多协议交互,而不必拘泥在网络层。这些类也提供了辅... 查看详情

socket编程

套接字使用TCP提供了两台计算机之间的通信机制。客户端程序创建一个套接字,并尝试连接服务器的套接字。当连接建立时,服务器会创建一个Socket对象。客户端和服务器现在可以通过对Socket对象的写入和读取来进行通信。java.n... 查看详情