0

我已经处理这个问题几天了,我无法弄清楚问题是什么。我正在尝试通过套接字从 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。连接正确打开,并且以相反的方式发送数据完美。

4

2 回答 2

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等。

于 2012-11-13T03:25:50.073 回答
0

事实证明,虽然 Davyd 非常正确,但实际问题在于缓冲区大小设置不正确。我在字节文件前面有一个空白,导致读取它时出现问题。下次对齐你的缓冲区/套接字读取:)

于 2012-11-16T19:04:45.593 回答