Reputation: 7943
I have been dealing with the issue for a few days now and I cannot figure out what the issue is. I am trying to send a sound file over a socket from iOS to a C# based server. The code is as follows:
Objective 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
On the C# side for reading the data in (will try to shorten the code down), it is as follows:
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
The issue that I have, is that I am sending over a .caf file recorded on the iPhone. However, when I try to play it back on the server machine, QuickTime tells me that the file cannot be played back. Also, the file size in bytes seems to be slightly shorter (about 20kb shorter) than the original. Any ideas? I apologize for throwing so much code up. Any help is greatly appreciated!
PS. The connection is open correctly and sending data the other way around works perfectly.
Upvotes: 0
Views: 243
Reputation: 7943
As it turns out that while Davyd is very much correct, the actual issue was in the buffer sizes not properly set up. I had a blank in front of the bytes file which caused issues in reading it. Align your buffers/socket read right next time :)
Upvotes: 0
Reputation: 4623
You need to write to the stream only if it has space available rather then assuming is is always ready. Implement delegate method:
[_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;
}
}
...
}
}
You may need to process other events such as NSStreamEventErrorOccurred
, NSStreamEventEndEncountered
, etc.
Upvotes: 1