Как отправить сообщение в формате Iso8583 на сервер с помощью C#
Чтобы получить данные с банковского сервера, они предоставят мне IP и номер порта. Я использую формат сообщений ISO8583 (библиотека OpenIso8583 из NuGet Manager) для отправки и получения сообщений. Пожалуйста, предоставьте мне решение о том, как отправлять сообщения ISO8583 на банковский сервер, используя IP-адрес и номер порта.
public void post () {
var msg = new Iso8583();
msg.MessageType = Iso8583.MsgType._0200_TRAN_REQ;
//Following feilds are mandotary to get balanace info
msg[Iso8583.Bit._003_PROC_CODE] = "820000";//balanace enquery
msg[Iso8583.Bit._102_ACCOUNT_ID_1] = "0021210020320000069";//bankid(002)branchid(121)accnumber(0020320000069)
//send iso message to server
var response = NetworkSend("192.32.179.171", 45510, msg);//ipaddress,port,msg
if (response[Iso8583.Bit._039_RESPONSE_CODE] == "000")
{
//success
// read data of iso message
}
}
private static Iso8583 NetworkSend(string ip, int port, Iso8583 msg)
{
// We're going to use a 2 byte header to indicate the message length
// which is not inclusive of the length of the header
var msgData = new byte[msg.PackedLength + 2];
// The two byte header is a base 256 number so we can set the first two bytes in the data
// to send like this
msgData[0] = (byte)(msg.PackedLength % 256);
msgData[1] = (byte)(msg.PackedLength / 256);
// Copy the message into msgData
Array.Copy(msg.ToMsg(), 0, msgData, 2, msg.PackedLength);
// Now send the message. We're going to behave like a terminal, which is
// connect, send, receive response, disconnect
var client = new TcpClient();
var endPoint = new IPEndPoint(IPAddress.Parse(ip), port);
client.Connect(endPoint);
var stream = client.GetStream();
// Send the packed message
stream.Write(msgData, 0, msgData.Length);
// Receive the response
// First we need to get the length of the message out of the socket
var lengthHeader = new byte[2];
stream.Read(lengthHeader, 0,2);//this line giving error
// Work out the length of the incoming message
var rspLength = lengthHeader[0] * 256 + lengthHeader[1];
var rspData = new byte[rspLength];
// Read the bytes off the network stream
stream.Read(rspData, 0, rspLength);
// Close the network stream and client
stream.Close();
client.Close();
// Parse the data into an Iso8583 message and return it
var rspMsg = new Iso8583();
rspMsg.Unpack(rspData, 0);
return rspMsg;
}
2 ответа
Ваша первая проблема в упаковке сообщения. Значения msgdata[0] и msgdata[1] следует поменять местами, иначе хост ожидает гораздо больше, чем вы отправляете.
Что касается части, где вы ожидаете входящие данные, у меня была та же проблема, из-за фрагментации пакета. Что я сделал, так это добавил событие OnReceived в мой сокет, и в этом событии мое первое чтение проверило, были ли полученные данные больше 1 байта. Если это так, первые 2 байта были моим индикатором длины, и я продолжал читать и добавлять в буфер до тех пор, пока не достигнул общего значения, указанного индикатором длины, или до истечения времени ожидания. Я сделал это путем рекурсивного повторного входа в событие OnReceived, пока не осталось байтов для чтения.
Вот способ отправить сообщение iso по сети
public static string Send(Iso8583 msg, string IP, int Port)
{
var messagebits = msg.ToMsg();
string result = "";
try
{
TcpClient tcpclnt = new TcpClient();
tcpclnt.Connect(IP, Port);
Stream stream = tcpclnt.GetStream();
ASCIIEncoding asen = new ASCIIEncoding();
stream.Write(messagebits, 0, messagebits.Length);
var lengthHeader = new byte[2];
stream.Read(lengthHeader, 0, 2);
var rspLength = lengthHeader[0] * 256 + lengthHeader[1];
var rspData = new byte[rspLength];
stream.Read(rspData, 0, rspLength);
tcpclnt.Close();
Iso8583 msgIso = new Iso8583();
msgIso.Unpack(rspData, 0);
}
catch (Exception) { }
return result;
}