首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >C# networking TcpClient

C# networking TcpClient
EN

Stack Overflow用户
提问于 2011-10-08 01:06:04
回答 2查看 1.9K关注 0票数 0

有人能告诉我为什么“经历了吗?”仅当Thread.Sleep的参数< 110时才打印?

Update <7.X.2011 5 5PM ET>:我认为正在发生的事情是服务器端被客户端写(A)饱和了,然后以某种方式影响了在连接关闭之前发送数据的能力。

每当迭代次数超过165xx时,“通过?”不发送,则只要迭代次数小于165xx,就会发送该字符串。这个数字是在睡眠时间107及以后达到的。值为107的休眠值有时会发送字符串,这取决于后台运行的其他(OS)线程。

迭代值永远不会超过165xx,即使当睡眠设置为一个很大的值(例如2秒)时也是如此,这使我相信网络缓冲区已满。

代码语言:javascript
复制
    static void fClient()
    {
        int iterations = 0;
        TcpClient client = new TcpClient("localhost", 22320);

        BinaryReader br = new BinaryReader(client.GetStream());
        BinaryWriter bw = new BinaryWriter(client.GetStream());
        while (true)
        {
            try
            {
                if (client.Available > 0)
                {
                    Console.WriteLine(br.ReadString());
                }
                else
                {
                    bw.Write("a");
                    iterations++;
                }
            }
            catch (IOException)
            {
                Console.WriteLine("EXCEPTION");
                //exception always reads: Unable to write....
                // (thrown by bw.Write("a"))
                // show iterations count
                break;
            }
        }
    }

    static void Main(string[] args)
    {
        TcpListener server = new TcpListener(22320);
        server.Start();

        new Thread(fClient).Start();
        Thread.Sleep(200);

        TcpClient client = server.AcceptTcpClient();

        BinaryWriter binWrite = new BinaryWriter(client.GetStream());
        binWrite.Write("Went Through?");
        binWrite.Flush();
        client.Close();
    }
EN

回答 2

Stack Overflow用户

发布于 2011-10-08 03:08:14

我也认为代码很简单:)但是这个代码没有使用睡眠来同步线程。

代码语言:javascript
复制
static Semaphore Go = new Semaphore(0, 1);

static void Server()
{
    TcpListener server = new TcpListener(22320);
    server.Start();
    Go.Release();

    while (true)
    {
        TcpClient client = server.AcceptTcpClient();
        new Thread((x) => ServerTask(x)).Start(client);
    }
}

static void ServerTask(object clnObj)
{
    TcpClient client = clnObj as TcpClient;

    BinaryReader br = new BinaryReader(client.GetStream());
    BinaryWriter bw = new BinaryWriter(client.GetStream());

    string s = "FromServer: " + br.ReadString();
    bw.Write(s);

    client.Close();
}

static void Client(int i)
{

    TcpClient client = new TcpClient();
    client.Connect("localhost", 22320);

    BinaryReader br = new BinaryReader(client.GetStream());
    BinaryWriter bw = new BinaryWriter(client.GetStream());

    bw.Write(i.ToString());
    Console.WriteLine(br.ReadString());

    client.Close();

}

static void Main(string[] args)
{
    Thread t = new Thread(() => Server());
    t.IsBackground = true;
    t.Start();
    Go.WaitOne();

    Console.WriteLine("Server Started....");
    Parallel.For(0, 21, (i) => Client(i));
    Console.WriteLine("Clients Processed");
    Console.ReadLine();
}
票数 0
EN

Stack Overflow用户

发布于 2011-10-08 09:21:10

我想我终于想通了。

两个端点A和B相互通信:A <-> B

当A向B发送一条消息,然后关闭它的TcpClient对象时,我假设B上的TcpClient.Available属性仍然会在收到消息时列出来自A的最后一条消息,然后BinaryReader.ReadString()将能够检索该消息,即使A中断了TCP/IP连接。

我观察到,情况并不总是如此,现在我想我明白为什么了。

在A关闭连接之后,如果B只从网络读取,那么它将能够从A获取最后一条消息,并且Available属性将反映该消息的存在。但是,如果B对网络执行写操作,则该写操作将立即检测到断开的连接,并使任何后续的读/写操作失败,即使可用属性返回>0。

因此,实际上我确实正确地理解了可用的属性,但今天了解到有例外,当属性不会像预期的那样运行时。

如果我错了,请纠正我。现在来更改我的应用程序。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/7690520

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档