我想清空套接字的读缓冲区,所以我编写了以下代码...
byte[] tempBuffer = new byte[1024];
int readCount = 0;
while ((readCount = tcpSocket.GetStream().Read(tempBuffer, 0, tempBuffer.Length)) != 0)
{
// do with tempBuffer
}
Run Code Online (Sandbox Code Playgroud)
但是Read()方法被阻塞所以我添加了tcpSocket.ReceiveTimeout = 1; .它就像以前一样工作.
据我所知,这通常用在C++中.我怎么解决这个问题?
我有一个 do while 循环,它从对象读取缓冲区,而NetworkStreamwhile 条件是networkStream.CanRead只要它可以读取,它就应该继续从缓冲区读取。唯一的问题是,当我从缓冲区读取并转换为字符串时,其中没有任何内容。即它是空的。
为什么会发生这种情况?
这是一个 ASP.NET(VS2005) 应用程序
@dtb代码信息:
我正在传递一个NetworkStream对象networkStream
// between 2 functions in a loop
{
SendMessage(networkStream, message);
ReadMessage(networkStream);
}
Run Code Online (Sandbox Code Playgroud)
有趣的是,如果它重新连接并再次连接,发送/读取工作正常。NetworkStream这实际上是发送(我在这里没有遇到异常)或对象重用的问题吗?这在测试 TCP 服务器上本地工作正常,但在生产中(Windows Server 2003)时我遇到了上述问题(即无法从流中读取任何内容 - 直到我实际超时(退出循环)之后) 10秒)
ReadMessage(networkStream)
{
if (networkStream != null && networkStream.CanRead)
{
byte[] myReadBuffer = new byte[1024];
StringBuilder myCompleteMessage = new StringBuilder();
do
{
int numberOfBytesRead = networkStream.Read(myReadBuffer, 0, myReadBuffer.Length);
string messageRead = Encoding.ASCII.GetString(myReadBuffer, 0, numberOfBytesRead);
myCompleteMessage.Append(messageRead);
} while (networkStream.CanRead);
}
}
Run Code Online (Sandbox Code Playgroud) 我刚刚问了一个关于如何发送大于 SendBufferSize 的数据的问题,答案是将分几个部分发送。
我的第二个问题是如何接收这些数据?它会在网络流中完整还是会被分割。
假设我在TCP上实现了简单的协议,其中每条消息由以下内容组成:
int指示数据长度.阅读这样的消息,我想要像:
int length = input.ReadInt();
byte[] data = input.ReadBytes(length);
Run Code Online (Sandbox Code Playgroud)
使用Socket.Receive或NetworkStream.Read读取可用的字节数.我希望调用ReadBytes阻塞,直到length字节可用.
是否有一种简单的方法可以执行此操作,而无需循环读取,在等待剩余数据的偏移处重新启动?
在一个真正的应用程序中,读取应该可以在异步或后台线程上完成,但我暂时忽略了它.重要的是能够在所有数据都可用之前读取不完整.
我知道我可以自己缓冲数据,我知道如何做到这一点.它只是一个循环Receive,在下一个偏移处继续.我要求的是,如果有一个可重用的实现这样的循环,而不需要任何类型的自有循环(或者可重用的Async实现,当所有数据都可用时完成).
我正在使用 DirectShow.Net 库创建一个过滤器图,该过滤器图通过使用 http 地址和 WM Asf Writer 来流式传输视频。然后,在网页上,我可以使用对象元素在 Windows Media Player 对象中呈现视频源。所以现在我很好奇是否可以使用某种类型的 FilterSource 读取该 http 地址。我看到有些人使用 AsyncReader 作为 IBaseFilter,然后将其转换为 IFileSourceFilter 并调用 load 方法并向其传递网络的 url。但我无法使用“http://localhost:8080”的 url 成功执行此操作。我猜这是因为它不是实际的“文件源”。我尝试在 IFileSourceFilter Load 方法中使用 AMMediaType ,其主要类型为 MediaType.URLStream ,子类型为 MediaSubType.Asf ,但仍然没有运气。如果有人能帮助我解决这个问题,我会象征性地吻他们,因为我已经为此工作了一段时间了。请哦请帮助我。
在我的代码中,我相应地创建了 FilterGraph 和 CaptureGraph。然后创建一个 AsyncReader 实例并将其转换为 IBaseFilter。接下来,我将其转换为 IFileSourceFilter 并调用 Load 方法,并向其传递“http://localhost:8080”url。然后将其添加到 FilterGraph。然后,我创建视频渲染过滤器并添加它,但是当我尝试调用 CaptureGraphBuilder2 对象的 RenderStream 方法时,它会抛出“未指定错误”异常。这是我的代码...
var fGraph = new FilterGraph() as IFilterGraph2;
var cGraph = new CaptureGraphBuilder2() as ICaptureGraphBuilder2;
cGraph.SetFiltergraph(fGraph);
var tmp = new AsyncReader() as IBaseFilter;
// This is where I tried …Run Code Online (Sandbox Code Playgroud) 我有一个客户端 - 服务器应用程序,其中服务器传输一个4字节的整数,指定下一次传输的大小.当我在客户端读取4字节整数(指定FILE_SIZE)时,下次读取流时,我得到FILE_SIZE + 4个字节读取.
从此流中读取时是否需要将偏移量指定为4,或者是否有办法自动推进NetworkStream以使我的偏移量始终为0?
服务器
NetworkStream theStream = theClient.getStream();
//...
//Calculate file size with FileInfo and put into byte[] size
//...
theStream.Write(size, 0, size.Length);
theStream.Flush();
Run Code Online (Sandbox Code Playgroud)
客户
NetworkStream theStream = theClient.getStream();
//read size
byte[] size = new byte[4];
int bytesRead = theStream.Read(size, 0, 4);
...
//read content
byte[] content = new byte[4096];
bytesRead = theStream.Read(content, 0, 4096);
Console.WriteLine(bytesRead); // <-- Prints filesize + 4
Run Code Online (Sandbox Code Playgroud) 这与C#有关.我们有一种情况需要将整个源流复制到目标流中,除了最后16个字节.
编辑:流可以达到40GB,所以不能做一些静态byte []分配(例如:.ToArray())
看看MSDN文档,似乎只有当返回值为0时我们才能可靠地确定流的结束.返回值介于0和之间the requested size可能意味着字节"当前不可用"(这究竟意味着什么?)
目前,它按如下方式复制每个字节.inStream并且outStream是通用的 - 可以是内存,磁盘或网络流(实际上也是一些).
public static void StreamCopy(Stream inStream, Stream outStream)
{
var buffer = new byte[8*1024];
var last16Bytes = new byte[16];
int bytesRead;
while ((bytesRead = inStream.Read(buffer, 0, buffer.Length)) > 0)
{
outStream.Write(buffer, 0, bytesRead);
}
// Issues:
// 1. We already wrote the last 16 bytes into
// outStream (possibly over the n/w)
// 2. last16Bytes = …Run Code Online (Sandbox Code Playgroud) 对不起,如果这很难理解,第一次尝试C#.
我试图在连接到服务器的客户端之间进行简单的公共"聊天".我已经尝试将整数传递给服务器并打印出来,一切都很好,但是,当我切换到字符串时,它似乎只能传递1个字符(因为ns.Write(converted, 0, 1);).如果我ns.Write(converted,0,10)在输入少于10个字符的消息时将ns.Write增加到一切崩溃(客户端和服务器).
服务器代码:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Net.Sockets;
namespace MultiServeris
{
class Multiserveris
{
static void Main(string[] args)
{
TcpListener ServerSocket = new TcpListener(1000);
ServerSocket.Start();
Console.WriteLine("Server started");
while (true)
{
TcpClient clientSocket = ServerSocket.AcceptTcpClient();
handleClient client = new handleClient();
client.startClient(clientSocket);
}
}
}
public class handleClient
{
TcpClient clientSocket;
public void startClient(TcpClient inClientSocket)
{
this.clientSocket = inClientSocket;
Thread ctThread = new Thread(Chat);
ctThread.Start();
}
private void Chat() …Run Code Online (Sandbox Code Playgroud) 在同一台计算机上我有2个控制台应用程序.(客户端将文件发送到服务器)
在开始之前,我只想提一下我正在使用这两个async功能:
阅读NetworkStream:
public static Task<int> ReadAsync1(this NetworkStream networkStream, byte[] buffer, int offset, int size)
{
return Task<int>.Factory.FromAsync(networkStream.BeginRead, networkStream.EndRead, buffer, offset, buffer.Length, networkStream);
}
Run Code Online (Sandbox Code Playgroud)
写信给NetworkStream:
public static Task WriteAsync1(this NetworkStream networkStream, byte[] buffer, int offset, int size)
{
return Task.Factory.FromAsync(networkStream.BeginWrite, networkStream.EndWrite, buffer, offset, buffer.Length, networkStream);
}
Run Code Online (Sandbox Code Playgroud)
我的客户代码:
(让我们拿一个我知道它的大小的简单文件)

我的发送代码:
NetworkStream ns = socketForServer.GetStream();
ns.WriteAsync1(File.ReadAllBytes(@"c:\r\1.jpg"), 0, 1593899);
ns.Flush();
Run Code Online (Sandbox Code Playgroud)
我的服务器代码 :(阅读...)
byte[] d = new byte[1593899];
networkStream.Read(d, 0, d.Length);
File.WriteAllBytes(@"c:\r\2.jpg",d);
Run Code Online (Sandbox Code Playgroud)
结果:
2.jpg 写道:

那问题出在哪里?
2.jpg …
下面的代码块说明了如何使用 TCP 和网络流发送 HTTP 请求。然而,无论应用任何过滤,每个请求始终平均消耗 60 秒。无论是单个数据还是一千个数据到达,延迟都保持不变。为什么会持续60秒?是否没有选项可以缩短此时间或设置立即获取数据而无需等待?
// Specify the server and port
string server = "xxx.com";
int port = 80;
// Specify the HTTP request
string httpRequest = "POST /ApiPrefixNameHere/ControllerNameHere/ActionNameHere HTTP/1.1\r\nHost: xxx.com\r\naccept: text/plain\r\nContent-Type: application/json-patch+json\r\nContent-Length: 27\r\n\r\n{\"ParameterNameHere\":\"1580\"}";
// Create a TcpClient
using (TcpClient tcpClient = new())
{
await tcpClient.ConnectAsync(server, port);
using (NetworkStream networkStream = tcpClient.GetStream())
using (StreamWriter writer = new(networkStream, Encoding.ASCII))
using (StreamReader reader = new(networkStream, Encoding.ASCII))
{
// Send the HTTP request
await writer.WriteAsync(httpRequest);
await writer.FlushAsync();
// Read the response …Run Code Online (Sandbox Code Playgroud)