【问题标题】:Truncated incoming socket message截断的传入套接字消息
【发布时间】:2012-02-29 18:48:27
【问题描述】:

此代码是来自我的套接字侦听器程序的尖晶石。问题是我没有收到全部信息。我收到 1382 个字节。但是,正如您在代码中看到的,我已将数组大小定义为 15000。

namespace Listener 
{ 
    class Server 
    { 
        static void Main(string[] args) 
        { 
            IPAddress localAddr = IPAddress.Parse(args[0]); 
            System.Console.WriteLine("The local IP is {0}",  
localAddr); 
            Int32 port = int.Parse(args[1]); 
            System.Console.WriteLine("The port is {0}", port); 
            TcpListener myListener = new TcpListener(localAddr,  
port); 
            byte[] bytes = new byte[15000]; 
            string sem = ""; 
            do 
            { 
                Console.Write("Waiting"); 
                myListener.Start(); 
                Socket mySocket = myListener.AcceptSocket(); 
                // receiving the hl7 message             
                mySocket.Receive(bytes); 
                string receiveMessage =  
Encoding.ASCII.GetString(bytes); 
                // write out the hl7 message to a receiving  
folder 
                DateTime currentDate = DateTime.Now; 
                long eTicks = currentDate.Ticks; 
                System.IO.File.WriteAllText(@"y:\results\" +  
eTicks + ".hl7", receiveMessage); 
                // build the acknowledgemnent message to send  
back to the client 
                try 
                { 

感谢大家的帮助。

【问题讨论】:

    标签: bytearray truncated


    【解决方案1】:

    Socket.Receive() 每次调用只会获取第一个数据报。验证客户端在第一次调用中发送了超过 1382 个字节。

    如果要发送更多数据,则让客户端将其排队等待一次发送调用,或者连续调用 Receive() 并附加到另一个缓冲区,直到您知道它已完成。

    编辑例如: 您正在寻找的是非阻塞 IO。一种实现它的方法是here。如果每个客户端连接都有一个类,它可能如下所示:

    internal class Server
    {
        private static void Main(string[] args)
        {
            IPAddress localAddr = IPAddress.Parse(args[0]);
            System.Console.WriteLine("The local IP is {0}",
                                     localAddr);
            Int32 port = int.Parse(args[1]);
            System.Console.WriteLine("The port is {0}", port);
            TcpListener myListener = new TcpListener(localAddr,
                                                     port);
            byte[] bytes = new byte[15000];
            string sem = "";
            do
            {
                Console.Write("Waiting");
                myListener.Start();
                Socket mySocket = myListener.AcceptSocket();
                var clientConn = new ClientConnection(mySocket);
            } while (true);
        }
    }
    
    public class ClientConnection
    {
        private const int BUFFER_SIZE = 15000;
        readonly private byte[] _buffer = new byte[BUFFER_SIZE];
        readonly private Socket _socket;
        readonly private StringBuilder _output = new StringBuilder();
    
        public ClientConnection(Socket socket)
        {
            _socket = socket;
            _socket.BeginReceive(_buffer, 0, BUFFER_SIZE, SocketFlags.None, ReadCallback, null);
        }
    
        private void ReadCallback(IAsyncResult ar)
        {
            var read = _socket.EndReceive(ar);
    
            if (read > 0)
            {
                // receiving the hl7 message             
                string receiveMessage = Encoding.ASCII.GetString(_buffer, 0, read);
                _output.Append(receiveMessage);
    
                _socket.BeginReceive(_buffer, 0, BUFFER_SIZE, SocketFlags.None, ReadCallback, null);
            }
            else
            {
    
                // write out the hl7 message to a receiving  folder
                DateTime currentDate = DateTime.Now;
                long eTicks = currentDate.Ticks;
                System.IO.File.WriteAllText(@"y:\results\" + eTicks + ".hl7", _output.ToString());
    
                SendAcknowledgement();
            }
        }
    
        private void SendAcknowledgement()
        {
            // build the acknowledgemnent message to send back to the client 
        }
    }
    

    我没有对此进行验证,但它应该能让您朝着正确的方向前进。我假设当客户端完成发送数据时,服务器应该停止读取它。我还假设您的 do { } 是等待新连接的无限循环的开始。您还可以使用 BeginAccept() 使该部分代码成为非阻塞的,但这取决于您的用例是否需要。

    请注意,以这种方式打开的每个连接都会产生一个新的 ThreadPool 线程。

    【讨论】:

    • Jay 听起来会很完美。你能提供一个代码示例,它可以在没有 Receive() 命令永远阻塞的情况下做到这一点吗?
    • Jay,我将您的想法作为我的代码的基础,并将在今天早上与客户一起测试它。我会将其标记为已回答并在必要时进行更新。再次感谢您的帮助。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-08-23
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多