有人能告诉我为什么“经历了吗?”仅当Thread.Sleep的参数< 110时才打印?
Update <7.X.2011 5 5PM ET>:我认为正在发生的事情是服务器端被客户端写(A)饱和了,然后以某种方式影响了在连接关闭之前发送数据的能力。
每当迭代次数超过165xx时,“通过?”不发送,则只要迭代次数小于165xx,就会发送该字符串。这个数字是在睡眠时间107及以后达到的。值为107的休眠值有时会发送字符串,这取决于后台运行的其他(OS)线程。
迭代值永远不会超过165xx,即使当睡眠设置为一个很大的值(例如2秒)时也是如此,这使我相信网络缓冲区已满。
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();
}发布于 2011-10-08 03:08:14
我也认为代码很简单:)但是这个代码没有使用睡眠来同步线程。
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();
}发布于 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。
因此,实际上我确实正确地理解了可用的属性,但今天了解到有例外,当属性不会像预期的那样运行时。
如果我错了,请纠正我。现在来更改我的应用程序。
https://stackoverflow.com/questions/7690520
复制相似问题