클라이언트 프로그램에서 서버로 Xbox Kinect의 비디오 피드를 보내고 있습니다. 모든 것이 작동하지만 문제는 프레임 속도입니다. 무슨 일이 일어나고 있는지 나는 그것이 읽을 수있는 것보다 빨리 보내고 있다고 생각하고있다. 그래서 더 이상 보낼 수 없게되면 버퍼에 공간이 생길 때까지 보낼 내용을 저장하고 기다립니다. 이것이 내가 생각하는 이유는 꾸준히 성장하는 프로그램의 메모리 사용량을 볼 수 있기 때문입니다. 또한 내가 비디오 피드를 볼 때 약 10 초 전에 일어난 모든 일들과 더 느린 플레이 백을 볼 수 있기 때문에 어떤 프레임도 건너 뛰지는 않습니다. 그래서 내가 한 것은 프레임 속도를 5fps로 줄이는 것입니다. 그렇게 할 때 안정적입니다. 그러나 이것이 최선의 방법은 아닙니다. 내가 원하는 것은 버퍼가 꽉 차서 프레임을 건너 뛰고 프레임을 보낼 버퍼가있을 때까지 기다리는 것입니다. 문제가 될 수있는 것처럼 들리지만, 그렇다면 어떻게 수정해야합니까? 감사.C# NetworkStream/TCPClient를 통한 비디오 스트리밍
여기에 데이터를 보내고받는 코드가 있습니다.
private const int constChunkSize = 4096;
private const int constIntSize = 4;
protected TcpClient tcpObject;
protected NetworkStream tcpStream;
private void HandleComm()
{
try
{
tcpStream = tcpObject.GetStream();
byte[] totalByteAray = new byte[constIntSize];
byte[] message = new byte[constChunkSize];
byte[] fullMessage = new byte[0];
//this is how many bytes long the message will be
int totalBytes = 0;
int currentBytes = 0;
int chunkSize = constChunkSize;
int bytesRead = 0;
pingThread = new Thread(sendPing);
pingThread.Start();
while (true)
{
//skip reading if no data is available
//DataAvailable does not tell you when all the data has arrived
//it just tell you if some data has arrived
if (tcpStream.CanRead)
{
totalBytes = 0;
currentBytes = 0;
message = new byte[constChunkSize];
chunkSize = constChunkSize;
bytesRead = 0;
//The first 4 bytes of the message will always contain the length of the message, not including
//the first 4 bytes. This is how you know when to stop reading.
bytesRead = tcpStream.Read(totalByteAray, 0, constIntSize);
if (bytesRead == 0)
Disconnect();
//there are 4 bytes in a 32 bit number, so totalByteArrayContains 4 index that is a byte which is
//the 32 bit int that tells us how many bytes the whole message will be.
//now convert the totalByteArray to a 32bit int
totalBytes = BitConverter.ToInt32(totalByteAray, 0);
//fullMessage will contain the entire message but it has to be built message by message.
fullMessage = new byte[totalBytes];
//keep reading until we get all the data
while (currentBytes < totalBytes)
{
//when you send something over TCP it will some times get split up
//this is why you only read in chuncks, 4096 is a safe amount of bytes
//to split the data into.
if (totalBytes - currentBytes < constChunkSize)
{
chunkSize = totalBytes - currentBytes;
message = new byte[chunkSize];
}
bytesRead = tcpStream.Read(message, 0, chunkSize);
if (bytesRead == 0)
Disconnect();
//since we know each chunk will always come in at 4096 bytes if it doesn't that means that it's the end
//this part cuts off the extra empty bytes
//copy the message to fullMessage starting at current bytes and ending with the bytes left
message.CopyTo(fullMessage, currentBytes);
currentBytes += bytesRead;
}
//message has successfully been received
if (totalBytes != 0)
{
//if the message was a ping handle it here to reduce the size of the packet
if (fullMessage.Length == 1 && (fullMessage[0] == 0 || fullMessage[0] == 255))
{
//if the message matches your ping byte, then it's yours
if (fullMessage[0] == pingByte[0])
{
lastReceivedPing = DateTime.Now;
latency = (lastReceivedPing - lastSentPing).TotalMilliseconds;
if (OnPingReceived != null)
{
PingReceivedArgs args = new PingReceivedArgs();
args.receivedTime = lastReceivedPing;
args.latency = latency;
OnPingReceived(this, args);
}
}
//if it doesn't then send it off
else
{
sendData(fullMessage);
}
}
//if it's anything else pass it on
else
{
if (OnRawDataReceived != null)
{
RawDataReceivedArgs args = new RawDataReceivedArgs();
args.Data = new byte[fullMessage.Length];
fullMessage.CopyTo(args.Data, 0);
OnRawDataReceived(this, args);
}
}
totalBytes = 0;
}
}
}
}
catch
{
Disconnect();
}
}
protected void sendData(byte[] data)
{
try
{
//we need to know how big the data that we are sending will be
int length = data.Length;
//convert the 32bit int to a 4 byte array
byte[] lengthArray = BitConverter.GetBytes(length);
//init the main byte array that will be sent over
byte[] buffer = new byte[length + constIntSize];
//the first 4 bytes will contain the length of the data
lengthArray.CopyTo(buffer, 0);
//the rest of the buffer will contain the data being sent
data.CopyTo(buffer, constIntSize);
tcpStream.BeginWrite(buffer, 0, buffer.Length, new AsyncCallback(sendingData), tcpStream);
}
catch
{
Disconnect();
}
}
내가 Socket.Available 속성을 사용으로 보았다 (http://msdn.microsoft.com/en-us/library/system.net.sockets.socket.available.aspx) 얼마나 많은 데이터를 볼 수 있습니다 버퍼에 있지만 그것은 결코 가득 차는 것처럼 보입니다.
한 번에 하나의 프레임을 보내는 것에 대한 의미를 설명 할 수 있습니까? 코드를 게시 하시겠습니까? –