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