C# 在局域网中组织服务器和客户端之间连接的最佳方法?

C# 在局域网中组织服务器和客户端之间连接的最佳方法?,c#,android,xamarin,network-programming,C#,Android,Xamarin,Network Programming,我们有一个安卓应用程序,在一个特定的设备上就像一个服务器。所有其他设备都像客户端一样工作 服务器正在while循环中开始侦听传入的tcp连接。当接收到连接请求时,它会触发一个事件,因此该类的用户可以处理该请求,然后调用MyTcpServer类的WriteData方法来响应该请求。然后关闭已连接客户端的网络流,并开始新的循环迭代 在while循环中接收传入请求,然后在向客户端发送数据后关闭请求,这是一种好的做法吗 服务器和客户端使用下面列出的同一类: public class MyTcpServe

我们有一个安卓应用程序,在一个特定的设备上就像一个服务器。所有其他设备都像客户端一样工作

服务器正在while循环中开始侦听传入的tcp连接。当接收到连接请求时,它会触发一个事件,因此该类的用户可以处理该请求,然后调用MyTcpServer类的WriteData方法来响应该请求。然后关闭已连接客户端的网络流,并开始新的循环迭代

在while循环中接收传入请求,然后在向客户端发送数据后关闭请求,这是一种好的做法吗

服务器和客户端使用下面列出的同一类:

public class MyTcpServer
{
    #region Fields

    TcpListener listener;
    TcpClient client;

    #endregion 

    #region Properties 

    public bool IsRunning { get; private set; }

    #endregion

    #region Protected methods

    protected static byte[] StringToBytes(string input)
    {
        return Encoding.UTF8.GetBytes (input);
    }

    #endregion

    #region Public methods

    public void Start(string SERVER_IP, int PORT_NO)
    {
        if (IsRunning)
            return;
        IsRunning = true;

        Task.Run (() => {

            //---listen at the specified IP and port no.---
            IPAddress localAdd = IPAddress.Parse (SERVER_IP);

            listener = new TcpListener (localAdd, PORT_NO);
            Console.WriteLine ("Listening...");
            listener.Start ();

            while (true) {
                client = listener.AcceptTcpClient ();
                //---get the incoming data through a network stream---
                NetworkStream nwStream = client.GetStream ();
                byte[] buffer = new byte[client.ReceiveBufferSize];

                //---read incoming stream---
                int bytesRead = nwStream.Read (buffer, 0, client.ReceiveBufferSize);
                //---convert the data received into a string---
                string dataReceived = Encoding.ASCII.GetString (buffer, 0, bytesRead);

                var ip = ((IPEndPoint)client.Client.RemoteEndPoint).Address.ToString ();

                Array.Clear (buffer, 0, buffer.Length);
                Console.WriteLine ("[" + DateTime.Now.ToString ("HH:mm:ss") + "] Received : " + dataReceived);

                DataReceived?.Invoke (this, new Data () {Stream = nwStream, Message = dataReceived,
                    IP = ip
                });

                nwStream.Close();
            }
        });
    }

    public void WriteData(NetworkStream nwStream, byte[] responseData)
    {
        try {
            nwStream.Write (responseData, 0, responseData.Length);
        } catch (Exception e) {
            Console.WriteLine (e.ToString ());
        }
    }

    public void WriteData(string ip, int port, byte[] data)
    {
        try {
            var client = new TcpClient (ip, port);
            var nwstream = client.GetStream ();
            nwstream.Write (data, 0, data.Length);
            nwstream.Close ();
        } catch (Exception e) {
            Console.WriteLine (e.ToString ());
        }
    }

    public void Stop()
    {
        if (client != null)
            client.Close ();
        listener.Stop ();
        IsRunning = false;
    }

    #endregion

    public event EventHandler<Data> DataReceived;

    public class Data
    {
        public NetworkStream Stream {get;set;}
        public string Message {get;set;}
        public string IP {get;set;}
    }
}
公共类MyTcpServer
{
#区域字段
听者;
TCP客户机;
#端区
#区域属性
公共bool正在运行{get;private set;}
#端区
#区域保护方法
受保护的静态字节[]StringToBytes(字符串输入)
{
返回Encoding.UTF8.GetBytes(输入);
}
#端区
#区域公共方法
公共无效启动(字符串服务器\u IP,int端口\u编号)
{
如果(正在运行)
返回;
IsRunning=true;
Task.Run(()=>{
//---在指定的IP和端口号上侦听---
IPAddress localAdd=IPAddress.Parse(服务器IP);
侦听器=新的TcpListener(localAdd,端口号);
Console.WriteLine(“侦听…”);
Start();
while(true){
client=listener.AcceptTcpClient();
//---通过网络流获取传入数据---
NetworkStream nwStream=client.GetStream();
byte[]buffer=新字节[client.ReceiveBufferSize];
//---读取传入流---
int bytesRead=nwStream.Read(buffer,0,client.ReceiveBufferSize);
//---将接收到的数据转换为字符串---
string dataReceived=Encoding.ASCII.GetString(缓冲区,0,字节读取);
var ip=((IPEndPoint)client.client.RemoteEndPoint).Address.ToString();
Array.Clear(buffer,0,buffer.Length);
Console.WriteLine(“[”+DateTime.Now.ToString(“HH:mm:ss”)+“]已接收:“+dataReceived”);
DataReceived?.Invoke(这个,新数据(){Stream=nwStream,Message=DataReceived,
IP=IP
});
nwStream.Close();
}
});
}
public void WriteData(NetworkStream nwStream,字节[]responseData)
{
试一试{
nwStream.Write(responseData,0,responseData.Length);
}捕获(例外e){
Console.WriteLine(例如ToString());
}
}
public void WriteData(字符串ip,int端口,字节[]数据)
{
试一试{
var客户端=新的TCP客户端(ip、端口);
var nwstream=client.GetStream();
nwstream.Write(数据,0,数据长度);
nwstream.Close();
}捕获(例外e){
Console.WriteLine(例如ToString());
}
}
公共停车场()
{
如果(客户端!=null)
client.Close();
Stop();
IsRunning=false;
}
#端区
接收到公共事件事件处理程序数据;
公共类数据
{
公共网络流{get;set;}
公共字符串消息{get;set;}
公共字符串IP{get;set;}
}
}

这就是基本(现在是老式)HTTP的工作原理。客户端(浏览器)连接到服务器(web服务器),发送请求,读取响应,然后服务器关闭连接。现在有了“保持活动”这样的功能,可以在需要发出更多请求时保持连接的活动状态,因为TCP中的连接握手比较大,因此如果客户机在几秒钟内发出更多的请求,那么保持连接活动一段时间可能会很有用,或者在完成后让客户端关闭。如果客户端太多(比如200个),安卓设备能否在保持连接的情况下存活下来?它必须为每个这样的连接创建单独的线程(或者为读/写创建两个线程)。需要传输的数据是轻量级的,只需要在服务器数据更新时发送到客户端。我会使用WebSocket,它是TCP双工,您可以有客户端列表。net中有两个WebSocket框架,google it