gpt4 book ai didi

c# - 如何以多端口或其他方式使用 tcp 客户端连接到调制解调器?

转载 作者:太空宇宙 更新时间:2023-11-03 22:18:37 24 4
gpt4 key购买 nike

我有大约 5000 个调制解调器(瘦客户端),我想与它们通信,我的方法之一是这样的:string GetModemData(modemID),现在我有一个开放端口监听调制解调器的服务器,我正在使用套接字编程将数据发送到调制解调器(调用相关函数),但是当我想同时将数据发送到多个调制解调器并得到它们的响应时,我不知道我应该怎么做做?我可以将数据发送到一个调制解调器并等待其响应,然后将另一个数据发送到其他调制解调器(顺序),但问题是客户端应该等待很长时间才能得到答案(可能是一些不同的客户端想要从调制解调器获取一些信息所以他们都将等待进入 Q 或类似的东西),我认为解决这个问题的一种方法是使用多个端口并监听每个调制解调器到相关端口,但它占用太多端口并且也可能是内存使用超出我的可用内存空间,因此可能会发生一些丢失(这是真的吗?)。应该怎么办?我会考虑并行性,但我认为它不相关我应该等待一个端口,因为我不知道应该将当前接收到的数据传递给哪个客户端。我正在使用 asp.net。

目前我是这样做的:

private void StartListener()
{
ModemTcpListener = new TcpListener(ModemPort);
//ClientTcpListener = new TcpListener(ClientPort);

ModemTcpListener.Start();
ModemTcpListener.BeginAcceptTcpClient(new AsyncCallback(DoAcceptModemCallback), ModemTcpListener);
}

作为返回

private void DoReadModemCallback(IAsyncResult ar)
{
try
{
bool bRet = ar.AsyncWaitHandle.WaitOne(420000);
Modem modem = ar.AsyncState as Modem;
if (!bRet || modem == null)
{
return;
}
}
catch{}
// now send data to which client?????? if i'm going to use async????
}

和:

private void DoAcceptModemCallback(IAsyncResult ar)
{
try
{
ModemTcpListener.BeginAcceptTcpClient(new AsyncCallback(DoAcceptModemCallback), ModemTcpListener);
TcpClient tcpClient = ModemTcpListener.EndAcceptTcpClient(ar);
Modem modem= new Modem(tcpClient, "");
tcpClient.GetStream().BeginRead(modem.Buffer, 0, tcpClient.ReceiveBufferSize, new AsyncCallback(DoReadModemCallback), modem);
ModemTcpListener.BeginAcceptTcpClient(new AsyncCallback(DoAcceptModemCallback), ModemTcpListener);
Log.Write("a Modem connect ...");
}
catch (Exception ex)
{
}
}

最佳答案

这是一个跟踪所有客户的示例。为了便于阅读,我已经压缩了它。你真的应该把它分成多个类。

我正在使用 Pool(我刚刚创建并提交)和 SimpleServer。这两个类都是我目前正在构建的库的一部分(但远未完成)。

不要害怕打开 5000 个套接字,当您使用异步操作时,它们不会消耗太多资源。

    public class SuperServer
{
private List<ClientContext> _clients = new List<ClientContext>();
private SimpleServer _server;
private Pool<byte[]> _bufferPool;

public SuperServer()
{
// Create a buffer pool to be able to reuse buffers
// since your clients will most likely connect and disconnect
// often.
//
// The pool takes a anonymous function which should return a new buffer.
_bufferPool = new Pool<byte[]>(() => new byte[65535]);
}

public void Start(IPEndPoint listenAddress)
{
_server = new SimpleServer(listenAddress, OnAcceptedSocket);

// Allow five connections to be queued (to be accepted)
_server.Start(5);
}

// you should handle exceptions for the BeginSend
// and remove the client accordingly.
public void SendToAll(byte[] info)
{
lock (_clients)
{
foreach (var client in _clients)
client.Socket.BeginSend(info, 0, info.Length, SocketFlags.None, null, null);
}
}

// Server have accepted a new client.
private void OnAcceptedSocket(Socket socket)
{
var context = new ClientContext();
context.Inbuffer = _bufferPool.Dequeue();
context.Socket = socket;

lock (_clients)
_clients.Add(context);

// this method will eat very few resources and
// there should be no problem having 5000 waiting sockets.
context.Socket.BeginReceive(context.Inbuffer, 0, context.Inbuffer.Length, SocketFlags.None, OnRead,
context);
}

//Woho! You have received data from one of the clients.
private void OnRead(IAsyncResult ar)
{
var context = (ClientContext) ar.AsyncState;
try
{
var bytesRead = context.Socket.EndReceive(ar);
if (bytesRead == 0)
{
HandleClientDisconnection(context);
return;
}

// process context.Inbuffer here.
}
catch (Exception err)
{
//log exception here.
HandleClientDisconnection(context);
return;
}

// use a new try/catch to make sure that we start
// read again event if processing of last bytes failed.
try
{
context.Socket.BeginReceive(context.Inbuffer, 0, context.Inbuffer.Length, SocketFlags.None, OnRead,
context);
}
catch (Exception err)
{
//log exception here.
HandleClientDisconnection(context);
}
}

// A client have disconnected.
private void HandleClientDisconnection(ClientContext context)
{
_bufferPool.Enqueue(context.Inbuffer);
try
{
context.Socket.Close();
lock (_clients)
_clients.Remove(context);
}
catch(Exception err)
{
//log exception
}
}


// One of your modems
// add your own state info.
private class ClientContext
{
public byte[] Inbuffer;
public Socket Socket;
}

}

使用的类:

关于c# - 如何以多端口或其他方式使用 tcp 客户端连接到调制解调器?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4036251/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com