我几天来一直在处理这个问题,我无法弄清问题是什么。我试图通过套接字将声音文件从iOS发送到基于C#的服务器。代码如下:
目标C:
NSData * data = [NSData dataWithContentsOfFile:uri];
int length = 0;
int totalLen = [data length];
uint8_t buffer[1024];
Byte * readBytes = (uint8_t *)[data bytes];
//Tell the server what this is
int headerInt = 2;
NSData *header = [NSData dataWithBytes:&headerInt length:sizeof(int)];
[outputStream write:[header bytes] maxLength:sizeof(int)];
//Fill up the rest of the header (132 bytes total)
UTF8Char emptyHead[128];
[outputStream write:emptyHead maxLength:sizeof(char) * 128];
do
{
int indexLen = (1024 > (totalLen - length) ? (totalLen- length) : 1024);
memcpy(buffer, readBytes, indexLen);
int written = [outputStream write: buffer maxLength: 1024];
if (written < 0)
{
break;
}
length += written;
readBytes += written;
}
while (length < [data length]);
[self sendENDS]; //Inform the server I am done
在C#端读取数据(将尝试缩短代码),如下所示:
if (read > 0)
{
//Write this into an overall buffer
obj.bufferStream.Write(obj.buffer, 0, read);
obj.bufferStream.Flush();
if (obj.buffer.Length > 4)
{
//Check if the client sent an "end of stream" flag
byte[] checkBuff = obj.buffer.Skip(read - 4).Take(4).ToArray();
string terminator = ASCIIEncoding.ASCII.GetString(checkBuff);
if (terminator == "ENDS")
{
obj.readMe = false;
}
}
if (obj.readMe == true)
{
obj.buffer = new byte[ConnectionObject.bufferSize];//I keep forgetting to clear the buffer
localSocket.BeginReceive(obj.buffer, 0, ConnectionObject.bufferSize, SocketFlags.None, new AsyncCallback(recieve), obj);
}
}
//...the rest takes care of taking the obj.streamBuffer and writing it into a file along with handling other types of requests
我遇到的问题是,我发送的是iPhone上记录的.caf文件。但是,当我尝试在服务器计算机上播放时,QuickTime告诉我该文件无法播放。此外,文件大小(以字节为单位)似乎比原始文件略短(约20kb)。有任何想法吗?我为抛出这么多代码而道歉。非常感谢任何帮助!
PS。连接正确打开,反过来发送数据完美无缺。
答案 0 :(得分:1)
只有当空间可用时才需要写入流,而不是假设它始终准备就绪。 实现委托方法:
[_ostream setDelegate:self];
[_ostream scheduleInRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode];
[_ostream open];
- (void)stream:(NSStream*)aStream handleEvent:(NSStreamEvent)event
{
switch (event)
{
...
case NSStreamEventHasSpaceAvailable:
{
NSInteger written = [_ostream write:buffer maxLength:1024];
...
if (transferredDataLength == dataLength])
{
[_ostream close];
[_ostream removeFromRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode];
_ostream = nil;
}
}
...
}
}
您可能需要处理其他事件,例如NSStreamEventErrorOccurred
,NSStreamEventEndEncountered
等。
答案 1 :(得分:0)
事实证明,虽然Davyd非常正确,但实际问题是缓冲区大小没有正确设置。我在bytes文件前面有一个空白,这导致了读取它的问题。下次对齐你的缓冲区/套接字:)