在线程中访问NetworkStream

时间:2016-01-31 17:08:28

标签: c# multithreading server

我正在编写一个简单的tcp服务器和多个客户端项目。 所以我在这里问,我可以在线程中访问网络流吗? 为了使它更清晰,我列出了我的代码所做的一些步骤。 1。 如果客户想要连接我使用

创建一个新线程
Thread t2 = new Thread(delegate ()
{
AcceptTcpClient(server, y);//here it gets networkstream using server
});
t2.Start();

服务器是TcpListener server = new TcpListener(IPAddress.Any, 443);

所以我有一个gui。我可以看到谁连接到服务器。 现在我想获得该网络流,以便我可以进行通信。 我想当我双击我的数据网格视图列出客户端时,它会打开一个表单。 但我不知道我怎么可以访问该线程? 我应该在客户端连接时创建一个列表,它会得到一些id并使用该id来访问线程吗?

tl dr当我点击GUI中的按钮时,我需要来自线程的网络流。

编辑:我需要一个可以容纳网络流的地方。就像客户端连接时一样,它创建了一个新的网络流,所以我可以在点击GUI时使用它

1 个答案:

答案 0 :(得分:0)

如果您阅读TcpListener文档,您会注意到BeginAcceptTcpClient方法,它可以执行您想要的操作 - 异步接受TcpClient。扩展那里给出的例子,你将得到这个代码:

private class StreamParameter
{
    public TcpClient Client;
    public NetworkStream Stream;
    public byte[] Buffer;
}

public void DoBeginAcceptTcpClient(TcpListener listener)
{
    // Start to listen for connections from a client.
    Console.WriteLine("Waiting for a connection...");

    // Accept the connection. 
    // BeginAcceptSocket() creates the accepted socket.
    listener.BeginAcceptTcpClient(DoAcceptTcpClientCallback, listener);
}

// Process the client connection.
public void DoAcceptTcpClientCallback(IAsyncResult ar) 
{
    // Get the listener that handles the client request.
    TcpListener listener = (TcpListener) ar.AsyncState;

    // End the operation and display the received data on 
    // the console.
    TcpClient client = listener.EndAcceptTcpClient(ar);

    // Start listening for new client right away
    DoBeginAcceptTcpClient(listener);

    // Process the connection here
    NetworkStream stream = client.GetStream();

    StreamParameter param = new StreamParamater();
    param.Client = client;
    param.Stream = stream;
    param.Buffer = new byte[512];

    stream.BeginRead(param.Buffer, 0, 512, AsyncReadCallback, param);
}


public void AsyncReadCallback(IAsyncResult result)
{
    StreamParameter param = result.AsyncState as StreamParameter;

    int numBytesRead = param.Stream.EndRead(result);

    // Normal processing, sending reply, etc.
}  

这很简单。 BeginXYZ方法在后台启动操作,并在发生重大事件时调用回调(例如,BeginAccept中连接的客户端或BeginRead中的数据)。

在回调中,您调用结束异步过程的相应EndXYZ方法。所有其他处理都是正常的。

这可以处理无限数量的客户端,并且是最小的实现。当然,您需要添加异常处理等,但是您可以获得图片。