TCP 服务和 REST API

Posted

技术标签:

【中文标题】TCP 服务和 REST API【英文标题】:TCP Service & REST APIs 【发布时间】:2018-05-22 16:16:43 【问题描述】:

我有一个 GPS 跟踪器设备,我已经运行了一个 TCP/IP 服务器代码,它成功地在单独的线程中与每个设备建立了连接,并且设备在一分钟后继续发送其心跳,服务器回复开启。当我发送命令以获取设备位置时,它会为我提供位置并且一切正常。

现在我想使用网络服务从 android 设备获取位置,现在我很困惑如何从 Android 应用程序使用特定设备的运行线程?

【问题讨论】:

Android web 服务将是一个两端口应用程序。一个端口使用 IP 地址连接到 GPS 跟踪器设备。第二个端口是使用 HTTP 的网页应用程序(端口 8080)。在应用程序中,您将需要一个网页应用程序的方法来从 TCP 类中获取结果。 请解释一下,我想你已经理解我的问题了。如果我想编写 Rest 服务,那么我将如何使用我的设备连接呢? 您将使用 android 的 IP 地址使用 Webrequest(或任何 Web 方法,如 WebClient)从客户端连接到服务。响应将包含 GPS 跟踪器位置。 Rest 将从 TCP 连接中获取结果并将 TCP 字节重新格式化为字符串并在响应中发送给客户端。 但是设备会启动连接,然后继续在单独的线程中发送其心跳。为了获得它的位置,我需要发送位置,我需要发送位置获取流。如果设备在套接字 A 上发送其心跳,那么它将如何在任何其他套接字上给出其位置? 我在答案中分享我的代码。 【参考方案1】:
class Server

    TcpListener server = null;
    public Server(string ip, int port)
    
        IPAddress localAddr = IPAddress.Parse(ip);
        server = new TcpListener(localAddr, port);
        server.Start();
        StartListener();
    

    public void StartListener()
    
        try
        
            while (true)
            
                Console.WriteLine("Waiting for a connection... ");
                TcpClient client = server.AcceptTcpClient();
                Console.WriteLine("Connected!");

                Thread t = new Thread(new ParameterizedThreadStart(HandleDeivce));
                t.Start(client);
            
        
        catch (SocketException e)
        
            Console.WriteLine("SocketException: 0", e);
        
    

    public void HandleDeivce(Object obj)
    
        TcpClient client = (TcpClient)obj;
        NetworkStream stream = client.GetStream();

        string data = null;
        Byte[] bytes = new Byte[256];
        int i;

        while ((i = stream.Read(bytes, 0, bytes.Length)) != 0)
        
            data = Encoding.ASCII.GetString(bytes, 0, i);
            Console.WriteLine("1: Received: 0", data, Thread.CurrentThread.ManagedThreadId);

            if (data.StartsWith("##"))
            
                data = "LOAD";
            
            else
            
                data = "ON";
            

            byte[] msg = Encoding.ASCII.GetBytes(data);
            stream.Write(msg, 0, msg.Length);

            Console.WriteLine("1: Sent: 0", data, Thread.CurrentThread.ManagedThreadId);
        
        client.Close();
    

【讨论】:

【参考方案2】:

试着让代码看起来像这样

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml;
using System.Xml.Linq;
using System.Net;
using System.Net.Sockets;
using System.Threading;


namespace ConsoleApplication16

    class Program
    
        const string IP = "123.456.789.000";
        const int PORT_NUMBER = 1234;
        static AutoResetEvent autoEvent = new AutoResetEvent(false);

        static void Main(string[] args)
        
            GPSClient client = new GPSClient(IP, PORT_NUMBER);
            //start http client or equivalent here

            while (true)
            
                autoEvent.Reset();

                autoEvent.WaitOne();

                //wait for message from user/client on service port

                string message = client.message;

                //send message back to user/client

            
        
    
    public class WebServer
    

    
    public class GPSClient
    
        const int BUFFER_SIZE = 256;
        TcpClient client = null;
        NetworkStream stream = null;
        Byte[] bytes = new Byte[BUFFER_SIZE];
        public string message  get; set; 



        public GPSClient(string ip, int port)
        
            try
            

                Console.WriteLine("Connecting to Device... ");

                client.Connect(ip, port);
                Console.WriteLine("Connected!");
                stream = client.GetStream();

                stream.BeginRead(bytes, 0, BUFFER_SIZE, new AsyncCallback(HandleDeivce), stream);
            
            catch (SocketException e)
            
                Console.WriteLine("SocketException: 0", e);
            
        

        public void HandleDeivce(IAsyncResult ar)
        
            NetworkStream stream = ar.AsyncState as NetworkStream;

            string data = null;

            int i = stream.Read(bytes, 0, BUFFER_SIZE);

            data = Encoding.ASCII.GetString(bytes, 0, i);
            Console.WriteLine("Received: 0", data);
            message = data;

            if (data.StartsWith("##"))
            
               data = "LOAD";
            
            else
            
               data = "ON";
            

            byte[] msg = Encoding.ASCII.GetBytes(data);
            stream.Write(msg, 0, msg.Length);

            Console.WriteLine("Sent: 0", data);

            stream.BeginRead(bytes, 0, BUFFER_SIZE, new AsyncCallback(HandleDeivce), stream);
        
    

【讨论】:

谢谢,但是当这个 TCP 监听器正在运行时,我们如何编写一个 API 来读取单个参数。 我不确定您希望用户端口采用什么方法。所以在代码所属的地方添加了 cmets。如果你给我一个你想用于用户端口的方法的示例,我将更新代码。您可以使用太多不同的方法,并希望提供您需要的方法。 我已经在上面的答案中发布了我的代码。请给我指路。 我只看到一个用于 GPS 接口的端口。看不到用户界面的任何代码。我需要另一个连接的用户界面示例。 先生,这就是我要的。我不知道为什么我需要另一个连接以及该连接将如何使用此连接来读取设备参数。我没有用户界面的代码。我只需要开始编写那部分代码。

以上是关于TCP 服务和 REST API的主要内容,如果未能解决你的问题,请参考以下文章

Rest API 或 Soap 网络服务

如何同时使用 SOAP WCF 服务和 REST API

Rest API 和 Restful Web 服务之间的区别

ArcGIS Server REST 服务各类API的主要功能

我应该在同一台服务器上托管网站和 REST API 还是拆分?

REST API 服务器上资源的细粒度权限