我正在读一本名为" C#Network Programming"理查德布鲁姆。以下摘录指出Send()方法无法保证发送传递给它的所有数据。
byte[] data = new byte[1024]; int sent = socket.Send(data);
根据这段代码,你可能会想到这个 整个1024字节的数据缓冲区被发送到远程设备......但是这个 可能是一个糟糕的假设。取决于内部TCP的大小 缓冲区和传输的数据量有可能不是 提供给Send()mehtod的所有数据实际上都已发送。
但是,当我查看Microsoft文档https://msdn.microsoft.com/en-us/library/w93yy28a(v=vs.110).aspx时,它说:
如果您使用的是面向连接的协议,Send将阻止直到 除非设置了超时,否则将发送缓冲区中的所有字节
那是哪个?这本书于2004年出版,从那以后它有变化吗?
我打算使用异步套接字,所以我的下一个问题是,BeginSend()会发送所有数据吗?
答案 0 :(得分:1)
您所要做的就是阅读您引用的完全相同段落的其余部分。在同一句话中,你的引语甚至是例外。
如果使用面向连接的协议,Send将阻塞,直到发送缓冲区中的所有字节为止,除非使用Socket.SendTimeout设置超时。如果超出超时值,Send调用将抛出SocketException。 在非阻塞模式下,即使发送的数量少于缓冲区中的字节数,Send也可能成功完成。在应用程序发送缓冲区中的字节之前,应用程序负责跟踪发送的字节数并重试操作。
对于<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<link rel="stylesheet" href="//maxcdn.bootstrapcdn.com/bootstrap/3.3.1/css/bootstrap.min.css">
<!-- Optional theme -->
<link rel="stylesheet" href="//maxcdn.bootstrapcdn.com/bootstrap/3.3.1/css/bootstrap-theme.min.css">
<!-- Latest compiled and minified JavaScript -->
<script src="//maxcdn.bootstrapcdn.com/bootstrap/3.3.1/js/bootstrap.min.js"></script>
<script src="js/myExternalFile.js"></script>
<link rel="stylesheet" type="text/css" href="css/stylesheet.css">
<link href="https://fonts.googleapis.com/css?family=Allerta" rel="stylesheet">
<link href="https://fonts.googleapis.com/css?family=Crimson+Text" rel="stylesheet">
<title> My Website Name</title>
</head>
<body>
<ul class="nav">
<img src="logos/navbar-logo.png">
<li><a class="hover" href="#Contact">Contact</a></li>
<li><a class="active" href="#Careers">Careers</a></li>
<li><a class="active" href="#Services">Services</a></li>
<li><a class="active" href="#Drivers">Drivers</a></li>
</ul>
<div id="mycarousel" class="carousel slide" data-ride="carousel">
<!-- Indicators -->
<ol class="carousel-indicators">
<li data-target="#mycarousel" data-slide-to="0" class="active"></li>
<li data-target="#mycarousel" data-slide-to="1"></li>
<li data-target="#mycarousel" data-slide-to="2"></li>
<li data-target="#mycarousel" data-slide-to="3"></li>
<li data-target="#mycarousel" data-slide-to="4"></li>
</ol>
<!-- Wrapper for slides -->
<div class="carousel-inner" role="listbox">
<div class="item">
<img src="https://unsplash.it/2000/1250?image=397" data-color="lightblue" alt="First Image">
<div class="carousel-caption">
<h3>First Image</h3>
</div>
</div>
<div class="item">
<img src="https://unsplash.it/2000/1250?image=689" data-color="firebrick" alt="Second Image">
<div class="carousel-caption">
<h3>Second Image</h3>
</div>
</div>
<div class="item">
<img src="https://unsplash.it/2000/1250?image=675" data-color="violet" alt="Third Image">
<div class="carousel-caption">
<h3>Third Image</h3>
</div>
</div>
<div class="item">
<img src="https://unsplash.it/2000/1250?image=658" data-color="lightgreen" alt="Fourth Image">
<div class="carousel-caption">
<h3>Fourth Image</h3>
</div>
</div>
<div class="item">
<img src="https://unsplash.it/2000/1250?image=638" data-color="tomato" alt="Fifth Image">
<div class="carousel-caption">
<h3>Fifth Image</h3>
</div>
</div>
</div>
<!-- Controls -->
<a class="left carousel-control" href="#mycarousel" role="button" data-slide="prev">
<span class="glyphicon glyphicon-chevron-left" aria-hidden="true"></span>
<span class="sr-only">Previous</span>
</a>
<a class="right carousel-control" href="#mycarousel" role="button" data-slide="next">
<span class="glyphicon glyphicon-chevron-right" aria-hidden="true"></span>
<span class="sr-only">Next</span>
</a>
</div>
,还描述了行为:
您的回调方法应该调用EndSend方法。当您的应用程序调用BeginSend时,系统将使用单独的线程来执行指定的回调方法,并且将在EndSend上阻塞,直到Socket发送所请求的字节数或引发异常。
这不是一个非常好的设计,并且击败了回调的全部内容!请考虑使用SendAsync
代替(然后您仍然需要检查BeginSend
属性)。
答案 1 :(得分:0)
您引用的两个资源都是正确的。我认为措辞本来可以更好。 在文档中,MSDN也写了
也无法保证您发送的数据会显示在 网络立即。为了提高网络效率,潜在的 系统可能会延迟传输,直到大量传出 收集数据。
所以pre > code
方法阻塞,直到底层系统有空间来缓冲网络发送的数据。
成功完成Send方法意味着底层 系统有空间缓冲您的数据以进行网络发送。