0

此代码是我的套接字侦听器程序中的一个尖晶石。问题是我没有收到全部信息。我收到 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 
                { 

感谢您的帮助。

4

1 回答 1

1

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

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

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

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 线程。

于 2012-02-29T19:04:11.810 回答