【发布时间】:2020-04-18 11:55:10
【问题描述】:
从 GPS 设备接收数据: 我有一个 TCP 服务器设置,它从各种 GPS 跟踪器 (GT06) 接收数据。每个 GPS 设备发起请求,服务器接受它,并开始接收 NMEA 数据。 问题是当 GPS 连接到服务器时出现错误:“现有连接被远程主机强行关闭”
问题是我不知道如何通过 GPRS/TCP 连接从 GPS 接收数据。 有什么建议吗?
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
namespace T1
{
class Program
{
public class StateObject
{
public const int DEFAULT_SIZE = 1024; //size of receive buffer
public byte[] buffer = new byte[DEFAULT_SIZE]; //receive buffer
public int dataSize = 0; //data size to be received
public bool dataSizeReceived = false; //received data size?
public StringBuilder sb = new StringBuilder(); //received data String
public int dataRecieved = 0;
public Socket workSocket = null; //client socket.
public DateTime TimeStamp; //timestamp of data
public const int BufferSize = 256;
} //end class StateObject
public static AutoResetEvent allDone = new AutoResetEvent(false);
public static AutoResetEvent acceptDone = new AutoResetEvent(false);
static void Main(string[] args)
{
StartListening();
}
public static void StartListening()
{
// Data buffer for incoming data.
byte[] bytes = new Byte[1024];
// Establish the local endpoint for the socket.
// The DNS name of the computer
// running the listener is "host.contoso.com".
IPHostEntry ipHostInfo = Dns.Resolve(Dns.GetHostName());
IPAddress ipAddress = ipHostInfo.AddressList[0];
IPAddress local = IPAddress.Parse("103.118.16.129");
IPEndPoint localEndPoint = new IPEndPoint(ipAddress, 8821);
// Create a TCP/IP socket.
Socket listener = new Socket(AddressFamily.InterNetwork,
SocketType.Stream, ProtocolType.Tcp);
// Bind the socket to the local endpoint and listen for incoming connections.
try
{
listener.Bind(localEndPoint);
listener.Listen(100);
while (true)
{
// Set the event to nonsignaled state.
allDone.Reset();
// Start an asynchronous socket to listen for connections.
Console.WriteLine("Waiting for a connection...");
listener.BeginAccept(new AsyncCallback(AcceptCallback), listener);
// Wait until a connection is made before continuing.
allDone.WaitOne();
}
}
catch (Exception e)
{
Console.WriteLine(e.ToString());
}
// Console.WriteLine("\nPress ENTER to continue...");
// Console.Read();
}
private static void Send(Socket handler, String data)
{
// Convert the string data to byte data using ASCII encoding.
byte[] byteData = Encoding.ASCII.GetBytes(data);
// Begin sending the data to the remote device.
handler.BeginSend(byteData, 0, byteData.Length, 0,
new AsyncCallback(SendCallback), handler);
}
private static void Send(Socket handler, byte[] data)
{
// Convert the string data to byte data using ASCII encoding.
// byte[] byteData = Encoding.ASCII.GetBytes(data);
// Begin sending the data to the remote device.
handler.BeginSend(data, 0, data.Length, 0,
new AsyncCallback(SendCallback), handler);
}
private static void SendCallback(IAsyncResult ar)
{
try
{
// Retrieve the socket from the state object.
Socket handler = (Socket)ar.AsyncState;
// Complete sending the data to the remote device.
int bytesSent = handler.EndSend(ar);
Console.WriteLine("Sent {0} bytes to client.", bytesSent);
handler.Shutdown(SocketShutdown.Both);
handler.Close();
}
catch (Exception e)
{
Console.WriteLine(e.ToString());
}
}
public static void AcceptCallback(IAsyncResult ar)
{
// Signal the main thread to continue.
allDone.Set();
// Get the socket that handles the client request.
Socket listener = (Socket)ar.AsyncState;
Socket handler = listener.EndAccept(ar);
// Create the state object.
StateObject state = new StateObject();
state.workSocket = handler;
handler.BeginReceive(state.buffer, 0, StateObject.BufferSize, 0,
new AsyncCallback(ReadCallback), state);
}
static byte[] Unpack(string data)
{
//return null indicates an error
List<byte> bytes = new List<byte>();
// check start and end bytes
if ((data.Substring(0, 4) != "7878") && (data.Substring(data.Length - 4) != "0D0A"))
{
return null;
}
for (int index = 4; index < data.Length - 4; index += 2)
{
bytes.Add(byte.Parse(data.Substring(index, 2), System.Globalization.NumberStyles.HexNumber));
}
//crc test
byte[] packet = bytes.Take(bytes.Count - 2).ToArray();
byte[] crc = bytes.Skip(bytes.Count - 2).ToArray();
uint CalculatedCRC = crc_bytes(packet);
return packet;
}
static public UInt16 crc_bytes(byte[] data)
{
ushort crc = 0xFFFF;
for (int i = 0; i < data.Length; i++)
{
crc ^= (ushort)(Reflect(data[i], 8) << 8);
for (int j = 0; j < 8; j++)
{
if ((crc & 0x8000) > 0)
crc = (ushort)((crc << 1) ^ 0x1021);
else
crc <<= 1;
}
}
crc = Reflect(crc, 16);
crc = (ushort)~crc;
return crc;
}
static public ushort Reflect(ushort data, int size)
{
ushort output = 0;
for (int i = 0; i < size; i++)
{
int lsb = data & 0x01;
output = (ushort)((output << 1) | lsb);
data >>= 1;
}
return output;
}
public static void ReadCallback(IAsyncResult ar)
{
String content = String.Empty;
// Retrieve the state object and the handler socket
// from the asynchronous state object.
StateObject state = (StateObject)ar.AsyncState;
Socket handler = state.workSocket;
// Read data from the client socket.
int bytesRead = handler.EndReceive(ar);
if (bytesRead > 0)
{
if (state.buffer[3] == 1)
{
string input = BitConverter.ToString(state.buffer, 0, bytesRead).Replace("-", "");
Console.WriteLine("Recived {0} bytes to client.", input);
//byte[] bytes = Unpack(input);
//byte[] serialNumber = bytes.Skip(bytes.Length - 2).ToArray();
//byte[] response = { 0x78, 0x78, 0x05, 0x01, 0x00, 0x00, 0x00, 0x0 };
//serialNumber.CopyTo(response, 4);
//UInt16 sendCRC = crc_bytes(response.Take(response.Length - 2).ToArray());
//response[response.Length - 2] = (byte)((sendCRC >> 8) & 0xFF);
//response[response.Length - 1] = (byte)((sendCRC) & 0xFF);
//Send(handler, response);
// handler.Send(response);
}
else
{
// There might be more data, so store the data received so far.
//state.sb.Append(Encoding.ASCII.GetString(state.buffer, 0, bytesRead));
// Check for end-of-file tag. If it is not there, read
// more data.
// content = state.sb.ToString();
Console.WriteLine("Recived {0} bytes to client.", Encoding.ASCII.GetString(state.buffer, 0, bytesRead));
// SaveData(content);
// Not all data received. Get more.
handler.BeginReceive(state.buffer, 0, StateObject.BufferSize, 0,
new AsyncCallback(ReadCallback), state);
// }
}
}
}
}
}
【问题讨论】:
-
查看我的完整解决方案。有很多代码,因此您必须查看多个答案,因为每个答案的大小都有限制:stackoverflow.com/questions/44471975/…
-
我收不到登录信息
-
您只是在创建一个侦听器,因此请使用 IPAddres IP.Any。不需要 103.118.16.129。也不是 ipHostInfo.AddressList[0]。 AddressList[0] 可以是 IPV4 或 IPV6。一台丢失的机器具有索引为零的 IPV6 和索引一的 IPV4。还使用 AddressList 仅查看机器上的一个以太网接口,如果机器有多个接口,则代码可能无法正常工作。使用 IP.Any 查看所有接口。使用:IPEndPoint localEndPoint = new IPEndPoint(IPAddress.Any , 8821);
-
删除 While 会导致问题。侦听器自动侦听多个客户端连接。您的代码将执行 listener.BeginAccept(new AsyncCallback(AcceptCallback), listener);多次,这将给出一个例外。