Я пытаюсь создать простой эхо-сервер UDP, который отправляет обратно все входящие датаграммы с префиксом строки UTF8.
В моих попытках достичь этой цели мне удалось отправить обратно входящие данные, но когда я пытаюсь добавить к этим данным префикс строки: "You sent: "
, я получаю сообщение об ошибке writeDataUnsupported
Это мой код:
Я сделал ChannelInboundHandler
под названием Echo
, и все, что он делает: для каждой входящей датаграммы он отправляет строку "You sent: "
, а затем данные входящей датаграммы.
final class Echo: ChannelInboundHandler {
typealias InboundIn = ByteBuffer
typealias OutboundOut = ByteBuffer
var wroteResponse = false
static let response = "You sent: ".data(using: .utf8)!
func channelRead(ctx: ChannelHandlerContext, data: NIOAny) {
if !wroteResponse {
var buffer = ctx.channel.allocator.buffer(capacity: Echo.response.count)
buffer.write(bytes: Echo.response)
ctx.write(self.wrapOutboundOut(buffer), promise: nil)
wroteResponse = true
}
ctx.write(data, promise: nil)
}
func channelReadComplete(ctx: ChannelHandlerContext) {
ctx.flush()
wroteResponse = false
}
}
Затем я создал группу однопоточного цикла событий и назначил ей загрузочную программу дейтаграммы. Затем я привязал начальную загрузку к порту 4065.
let 🔂 = MultiThreadedEventLoopGroup(numThreads: 1)
let bootstrap = DatagramBootstrap(group: 🔂)
.channelOption(ChannelOptions.socket(SocketOptionLevel(SOL_SOCKET), SO_REUSEADDR), value: 1)
.channelInitializer { $0.pipeline.add(handler: Echo()) }
defer {
try! 🔂.syncShutdownGracefully()
}
try bootstrap
.bind(host: "127.0.0.1", port: 4065)
.wait()
.closeFuture
.wait()
Почему я всегда получаю это writeDataUnsupported
при попытке отправить строку: "You sent: "
?
2 ответа
Для DatagramChannel
вам нужно обернуть ByteBuffer
в AddressEnvelope
. Это также означает, что ваш ChannelInboundHandler должен работать с AddressedEnvelope<ByteBuffer>
.
Чтобы заставить ChannelInboundHandler
работать с AddressedEnvelope<ByteBuffer>
, как предлагает Норман Маурер, вы можете переписать Echo
так, чтобы оно выглядело больше:
final class Echo: ChannelInboundHandler {
typealias InboundIn = AddressedEnvelope<ByteBuffer>
typealias OutboundOut = AddressedEnvelope<ByteBuffer>
static let response = "You sent: ".data(using: .utf8)!
func channelRead(ctx: ChannelHandlerContext, data: NIOAny) {
var incomingEnvelope = unwrapInboundIn(data)
var buffer = ctx.channel.allocator.buffer(capacity: Echo.response.count + incomingEnvelope.data.readableBytes)
buffer.write(bytes: Echo.response)
buffer.write(buffer: &incomingEnvelope.data)
let envelope = AddressedEnvelope(remoteAddress: incomingEnvelope.remoteAddress, data: buffer)
ctx.write(wrapOutboundOut(envelope), promise: nil)
}
func channelReadComplete(ctx: ChannelHandlerContext) {
ctx.flush()
}
}
Похожие вопросы
Новые вопросы
swift
Swift - это безопасный, быстрый и выразительный язык программирования общего назначения, разработанный Apple Inc. для своих платформ и Linux. Swift с открытым исходным кодом. Используйте тег только для вопросов о языковых функциях или необходимости кода в Swift. Используйте теги [ios], [ipados], [macos], [watch-os], [tvos], [cocoa-touch] и [cocoa] для (не зависящих от языка) вопросов о платформах или фреймворках.