javascript NodeJS net.socket只接收第一条消息

q3qa4bjr  于 2023-03-28  发布在  Java
关注(0)|答案(2)|浏览(95)

有一个奇怪的问题,我不知道如何处理。试图使认证服务器的魔兽世界客户端应用程序。
事情是这样的:

const net = require('net')

const server = net.createServer((socket) => { 
    console.log('Client connected');    
    socket.removeAllListeners('data');
    socket.on('end', () => console.log('Client disconnected!'));    
    socket.on('close', () => console.log('Client closed connection to server.'));    
    socket.on('drain', () => console.log('Buffer drain!'));

    socket.on('data', function(data) {
        console.log(data)
        onData(socket, data)
    });       
    socket.pipe(socket);
}).on('error', (err) => {
    console.log('Server error:' + err)
  });

function onData(socket, data) {
    console.log(`data length`, data.length)

    if (data.length === 44) {
        socket.write(Buffer.from('0000007cdc3e6e9cabc0cb57332ee5086df1b1ccc491d685996af531b4ec807ed2c667010720b79b3e2a87823cab8f5ebfbf8eb10108535006298b5badbd5b53e1895e644b891f97f4daa96fca449ea98bd3c8da6963012888a89b8e572abff4294e05c4fc98baa31e99a00b2157fc373fb369cdd2f100', 'hex'),
        (err) => {
            if (err)
                console.log(err);
            console.log(`Write data end`);
            socket.end(); //<-- also tried without FIN, since response packet is 0x0 terminated
        })        
    }
    console.log('onData::End');
}

server.listen(3724, '127.0.0.1', function() { 
    console.log('Server is listening');
});

输出如下:

Server is listening
Client connected
<Buffer 00 08 28 00 57 6f 57 00 03 03 05 34 30 36 38 78 00 6e 69 57 00 55 52 75 72 b4 00 00 00 7f 00 00 01 0a 53 49 4c 56 45 52 4c 45 58 58>
data length 44
onData::End
Write data end

问题是,在Wireshark中,我看到来自客户端的下一个包,但JS代码没有接收到它,似乎停留在第一个包上。
在图片上,你可以看到第一个来自客户端的WoW协议请求,长度为84字节,然后是我的159字节的响应,然后是一个115字节的客户端请求,我没有得到。(根据Wireshark,数据包的结构是好的,因为它被解析了)
只是为了测试一下,我创建了一个小golang应用程序,具有相同的行为。

package main

import (
   "fmt"
   "net"
   "io"
   "encoding/hex"
)

func main() {
   listener, _ := net.Listen("tcp", "127.0.0.1:3724") 
   for {
      conn, err := listener.Accept() 
      if err != nil {
         continue
      }
      fmt.Println("New socket")
      go handleClient(conn) 
   }
}

func handleClient(conn net.Conn) {
   defer conn.Close() 

   buf := make([]byte, 0, 4096)
   tmp := make([]byte, 32)     
   for {      
       fmt.Println("Start read")
       n, err := conn.Read(tmp)
       fmt.Println("Stop read")
       if err != nil {
           if err != io.EOF {
               fmt.Println("read error:", err)
           }

           fmt.Println("EOF")
           break
       }
       buf = append(buf, tmp[:n]...)
       fmt.Println("total size:", len(buf))

       s := "0000007cdc3e6e9cabc0cb57332ee5086df1b1ccc491d685996af531b4ec807ed2c667010720b79b3e2a87823cab8f5ebfbf8eb10108535006298b5badbd5b53e1895e644b891f97f4daa96fca449ea98bd3c8da6963012888a89b8e572abff4294e05c4fc98baa31e99a00b2157fc373fb369cdd2f100"
       if len(buf) == 44 {
          data, err := hex.DecodeString(s)
          if err != nil {
              panic(err)
          }

          conn.Write(data)
       }
   }
   fmt.Println("total size:", len(buf))
}

它像预期的那样工作,这里是输出:

New socket
Start read
Stop read
total size: 32
Start read
Stop read
total size: 44 //<-- first packet end, after this point we send response to client
Start read
Stop read
total size: 76 //<-- start reading second packet (so we got the next one)
Start read
Stop read
total size: 108
Start read
Stop read
total size: 119
Start read

所以我的问题是我在NodeJS中搞砸了,它应该很简单,几乎没有代码,但我就是不知道。


1.第一个客户端数据包:45000054aaed4000800600007f0000017f000001e5920e8c52e913174311bd4b501820fa346e000000082800576f570003053430363878006e69570055527572b400000007f0000010a53494c5645524c455858
1.第二客户端数据包:45000073ab094000800600007f0000017f000001e5920e8c52e913434311bdc2501820fa5ece00000191280a5b88b457d77d8df421b06e3d5c77a26b61b35c7fad12cdad9b71959e45395db29a611163d1d446e4a9973bf4f714afb6b532d1b21b21bf3347de5aa780d270c01b1a43f15d510000

UPDATE:在NodeJS套接字上做了一个小客户端,模拟客户端行为,看起来在服务器提供的情况下工作正常。

Server is listening
Client connected
<Buffer 00 08 28 00 57 6f 57 00 03 03 05 34 30 36 38 78 00 6e 69 57 00 55 52 75 72 b4 00 00 00 7f 00 00 01 0a 53 49 4c 56 45 52 4c 45 58 58>
data length 44
onData::End
Write data end
<Buffer 00 00 00 7c dc 3e 6e 9c ab c0 cb 57 33 2e e5 08 6d f1 b1 cc c4 91 d6 85 99 6a f5 31 b4 ec 80 7e d2 c6 67 01 07 20 b7 9b 3e 2a 87 82 3c ab 8f 5e bf bf ... 69 more bytes>
data length 119
onData::End

所以这可能是WoW客户端和NodeJS套接字实现的特定问题。仍然不知道出了什么问题。

wf82jlnq

wf82jlnq1#

pipe()函数的作用是:在可读流变为可用时从该流读取数据,并将其写入目标可写流。
文档中的例子是一个echo服务器,它是一个发送它接收到的东西的服务器。套接字对象实现了可读和可写的流接口,因此它正在将它接收到的任何数据写回套接字
但我仍然认为问题一定在那里,并改变了其他功能

ig9co6j1

ig9co6j12#

有没有可能是你的服务器在与客户端的连接终止后调用了close事件?(我还没有看到你的客户端代码)
因为如果服务器调用close事件,那么它将无法从任何其他客户端连接/接收。一些WebSocket事件是保留的,即使您显式定义了事件,它们的日志也可能不会反映在这里。
也许您还可以尝试删除socket.close()行并检查会发生什么。

相关问题