Network Streams problem

Apprentice
Posts: 6
Joined: 2010.09
Post: #1
Hello there,
I'm doing game for an iPhone as my Final project in College.
I didnt touch any graphic yet just start from the low level - Networking

I wrote Thread Pooled Server on Java, (little one atm, just to handle connection and data transfer) now im working on the client...

all is fine just Objective-C i never learn before (C/C++/Java + web like PHP/JS/HTML) so I have some problem with a streams.

As far as i know to send data there need to do several steps:
create socket
open stream
send data
close stream

but here i have a problem with re-opening stream:

overall description of the program sequence flow

1)user input name, pass
2) tap login button
3) button handler: if button == login:
4)calling "createSocket" function
4.1) creating socket + return status
if status ok
5)calling "sendData:data" function and passing data (login info) to it
5.1) open stream
5.2) sending data + return status (data is received 100% success)
5.3) close stream
if status ok
6) changing view from "login" to "chat"
7)user input new message
8)tap send button
9) event handler: if button == Send:
10)calling "sendData:data" with new data (new message)
10.1)trying to open stream
10.2) program hang, error...

It looks like i found reason of error, as in official API docs says:
Quote:Once closed, the stream cannot be reopened.

but i cant leave stream open without closing as server never show received data unless stream is closed as server think that data transaction is still in progress.

Should i create new socket each time i want to send data? but it seems un-logic to me.

could you please Help me with advice?
Quote this message in a reply
Moderator
Posts: 1,560
Joined: 2003.10
Post: #2
If you don't want to create a new socket each time, you could add some sort of framing to your messages and have your server parse them while the connection is still open instead of waiting for it to close. It seems like you'd want to do this anyway so that the server could send some sort of confirmation back to the client that it received the message successfully.
Quote this message in a reply
Apprentice
Posts: 6
Joined: 2010.09
Post: #3
Thank you very much for quick replay

(Aug 22, 2011 12:19 PM)ThemsAllTook Wrote:  If you don't want to create a new socket each time
it is not about what i want or not, im asking how it should be? if all developers who working with a sockets create socket each time they send data, than ill do the same, no problem
I was just wondering is it right desition? is it the way it should be? as for example in C or Java u define socket just once and than just open/close streams, so i was pretty surprised that in Objective-C u cant open stream after u close it, even if u didnt delete your socket definition and still using same parameters...

(Aug 22, 2011 12:19 PM)ThemsAllTook Wrote:  you could add some sort of framing to your messages and have your server parse them while the connection is still open instead of waiting for it to close. It seems like you'd want to do this anyway so that the server could send some sort of confirmation back to the client that it received the message successfully.

I didnt touch yet any "read" part... All i know from the official API Docs that ill have to schedule it for run loop to delegate, it will let me to handle all incoming data as event and will prevent program from blocking and i will be able to receive data unexpectedly, what i exactly need.

but how should i do/ implement this framing? could you direct me on some example code?
Quote this message in a reply
Moderator
Posts: 1,560
Joined: 2003.10
Post: #4
(Aug 22, 2011 12:28 PM)Briksins Wrote:  it is not about what i want or not, im asking how it should be? if all developers who working with a sockets create socket each time they send data, than ill do the same, no problem
I was just wondering is it right desition? is it the way it should be? as for example in C or Java u define socket just once and than just open/close streams, so i was pretty surprised that in Objective-C u cant open stream after u close it, even if u didnt delete your socket definition and still using same parameters...

Well, I'd say just to think about what it means to open a new connection and whether it makes sense for your situation. If you're in continual communication with the server, it may make more sense to use just one socket and keep it open the whole time. If you're just sending messages back and forth occasionally, it may be more convenient to make a new connection each time you want to send something.

It does seem a bit arbitrary that Cocoa would make you create a new stream object rather than being able to reopen one after closing it, but I guess that's just the way they designed their API. You can always drop down to C and use the BSD socket API instead if you prefer.

(Aug 22, 2011 12:28 PM)Briksins Wrote:  but how should i do/ implement this framing? could you direct me on some example code?

Framing can be any information sent along in your stream that allows the server to distinguish between messages. For example, if you're only sending text data, you could send a null byte at the end of every message. The server could then seek for a null byte every time it receives new data, and if it finds one, snip out the preceding data and respond appropriately to it. You could also send a number indicating the number of bytes in the message at the beginning of each one, and the server would handle the message when it had received that many bytes, then expect another byte count and message to follow. There are plenty of other ways you can do it; anything that lets the server unambiguously figure out message boundaries in a stream of data will work.
Quote this message in a reply
Apprentice
Posts: 6
Joined: 2010.09
Post: #5
Thank you very much it is very helpful! I probably cant afford to keep constant connection open client->server as there might be other players banging to the server at the same port, so i think the best decision is to keep sending short messages and close connection, its not a problem to include socket creation line in to the sendData() code. but for read() i can create another constant open socket for the server->client communication as only server will contact client and there will not be any other client banging to that door.

how practically its possible?
//Read
CFStreamCreatePairWithSocket (*** myRead ***)
schedule for run loop
implement event handler for the loop

//Write
[obj sendData:data];

sendData:mydata
{
CFStreamCreatePairWithSocket(*** myWrite ***)
open stream
write mydata
close stream
delete socket
}
Quote this message in a reply
Post Reply