Усеченное входящее сокетное сообщение - PullRequest
0 голосов
/ 29 февраля 2012

Этот код является спином из моей программы прослушивания сокетов. Проблема в том, что я не понимаю всего сообщения. Я получаю 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 
                { 

Спасибо за любую помощь, ребята.

1 Ответ

1 голос
/ 29 февраля 2012

Socket.Receive () будет получать только первую дейтаграмму при каждом вызове. Убедитесь, что на первом вызове клиентской стороной было отправлено более 1382 байтов.

Если необходимо отправить больше данных, либо попросите клиента поставить их в очередь на один вызов Send, либо непрерывно вызывать 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.

...