PDA

View Full Version : Basic TCP/IP Data Sending


Douglas_O'Brien
2002.05.23, 11:55 PM
Is there any kind of libraries for C that make simple TCP/IP commands.

Like...

Send_Char("45.211.34.0",char Data);

And a command to get the next char out of the TCP/IP buffer?

Like...

Data=Get_Char();



Two simple commands like this would really make Network programming fun and easy.

swcrissman
2002.05.24, 01:45 AM
No, nothing quite that simple. You'll need to to use sockets, and create, bind, listen, and accept before getting to that point. Once you've gotten that covered, you can use the send and recv functions to do what you describe, using buffers of size 1, if that's what you want to do.

Once you understand them, sockets arent as terrible as they seem at first, but the system calls are very much c code, and I get the feeling that most new programmers don't feel to comfortable with them because everyone is learning in laguages that are higher level than that now (or at least it seems that way).

In any case, its like 3am here, so I'm too tired to post a more in depth example. I'll try an come back tomorrow night and write something that covers the socket calls a little further, if you're interested.

Spencer

RedWolf
2002.05.26, 01:19 AM
Sockets is the Unix way of doing it. The Macintosh specific way is to use Open Transport. There are a lot of similarities between the two. In either case, it does take some setup before you can send/receive data via TCP/IP.

I digress here a bit, but Java does make network programming a lot easier.

swcrissman
2002.05.26, 10:56 AM
Not to get the wrong idea, but as far as I'm concerned, sockets are the way you do things typically everywhere except classic Mac. Also, OS X is Unix at its core, so sockets really trump even Open Transport post OS 9.

Sorry I still havent gotten a sample up, are you still interested in getting one, O'Brien?

Spencer

Douglas O'Brien
2002.05.26, 08:29 PM
Yes, I would like to see a sample of whatever it is your talking about. That is if its not too much trouble for you.

If you just want to do basic sending to another machine, isn't the binding, listening, and so on...usually going to be the same. You could make a function like

Err Establish_Connection("TCP/IP Address Here");

And when it establishes or fails you can move on from there. And, you could assign a number to an adress with the establish command, and with the sending command, you could just pass the number of the machine you want to send to instead of the adress string.

Isn't connecting two computers universal enough for a command like this?

ClarustheDogCow
2002.05.26, 08:31 PM
There is a pretty good socket framework for OS 9 (and below) that might be what you want:
http://sourceforge.net/projects/gusi/

Codemattic
2002.05.27, 05:28 PM
check out OpenPlay (http://developer.apple.com/darwin/projects/openplay/) - its geared to networked games and works on Mac, Windows, and soon Linux.

hth,
Codemattic

Douglas O'Brien
2002.05.27, 11:23 PM
As for the sourceforge thing, I looked at that site, didn't know what was going on, then left.

As for OpenPlay, thats pretty good stuff. However....

There is a new game making environment called TNT Basic which uses OpenPlay for their network commands. I wrote some network programs that worked fine over a LAN in my and other peoples' home. Then, I tried over the Net with another TNT user. Neither of us had firewall or anything. We could join each others "games" and be in the waiting room. Then when the host clicked start, the connection broke down. The fact that the TCP/IP worked over LAN and didn't completely work over the Net made me think that the problem was with OpenPlay. The TNT Basic guy agreed. However, I'm sure that something like this would obviously be tested over the Net and work before being released, which makes me think its TNT's fault.

Any way, I'm not a very experienced C programmer but I downloaded OpenPlay and I'll take a look at it.

wadesworld
2002.06.01, 10:58 PM
The fact that the TCP/IP worked over LAN and didn't completely work over the Net made me think that the problem was with OpenPlay. The TNT Basic guy agreed.

Um, no offense but it sounds like you were both shooting in the dark and weren't very likely to hit on the source of the problem.

What you should have done was a packet capture to see what was actually getting sent and received.

But to answer your question, the simplest TCP/IP implementation consists of simply creating a socket, binding it to an interface and then sending the data. On the receiving side, you create a socket, bind to an interface and then listen for incoming data.

As to why there can't just be a send_data call which does it all, it's because there's questions which have to be answered first. Are you using UDP or TCP? And which interface do you want to send the data out? Those questions have to be answered, and that's what creating the socket and binding it to an interface does.

Wade

ibullard
2002.06.03, 11:55 PM
Beej's Guide to Network Programming (http://www.ecst.csuchico.edu/~beej/guide/net/) is my favorite tutorial of sockets programming. It's not going to give you a lot of easy to use API's but it'll teach the basics.

Douglas_O'Brien
2002.06.04, 09:00 PM
Thanks for the Beej URL.

I haven't read to far into it yet, but one thing it mentions is UPD vs. TCP. It says UDP doesn't always arrive, so the sender sends until it gets a message from the reciever that the receiver got the data. What if the receivers message didn't make it. I guess the host would keep sending, and each time the receiver gets another copy, it just trashes it and sends that it got it again. However, to know that it is another copy of a message that its already gotten, each message must have some ID. And if a thousand messages are sent, wouldn't it be horrible to compare all new messages to the ID's in the ID's already received list. Maybe I should just keep reading. And use TCP since it is stable.

OneSadCookie
2002.06.04, 10:20 PM
In the simplest possible case, you'll know that you've received all messages with id less than n, so you can throw away any message you get that doesn't have id exactly n (if it's less you've already received it; if it's more you don't want to receive it yet).

Obviously, this isn't the most efficient approach to take, but hey -- it'll work.

ibullard
2002.06.04, 10:23 PM
If you use UDP, you have to make your own system to determine whether packets are lost or not. You also have to deal with packets arriving unordered. One way of doing this is to give all packets a unique ID that can be used to put packets back in order and request missing packets after they haven't arrived after a timeout.

With TCP, you're guaranteed packet arrival and order but it's S L O W. If you're looking to make a game that's not turn-based you'll have to go the UDP route.

wadesworld
2002.06.05, 04:46 PM
You can check for reception of UDP packets and retransmit lost packets, but that pretty much goes against the whole purpose of UDP.

If you need to send packets and they absolutely must arrive, and must arrive in order, use TCP.

If your data can stand missing a packet or two, use UDP.

Most applications actually use both. TCP for things like logins, and UDP for application data.

ibullard
2002.06.05, 06:06 PM
A lot of games send out delta packets with regular full game state packets at certain intervals. When the game gets a delta packet it changes what it says to change and when the full game state arrives, it overrides the computed values with the absolute values. That way you can disgard all the packets you've recieved every time you get a full game state.

Douglas_O'Brien
2002.06.06, 09:28 PM
OK.

However, in response to OneSadCookies post, you can delete messages with a higher n value but only to a degree.

For Example...say a 1 is a received and a 0 is not....

11111111111011110111111100001111111010001111111111 1111111111111110111111110111110

If we have something like this....we can only crop off if n<12. And due to the seer number of pakets, each frame number cant have the same array location number, so you couldn't do a fast if test that way. I mentioned a bubble sort earlier I think, a radix or binary would be faster but still....

OneSadCookie
2002.06.06, 10:29 PM
I don't understand what you're saying.

This is the logic on the receiver's end of the channel for UDP. It's not very efficient, but it's a simple way to get stuff working.


last_packet_id = -1;

while(we_want_to_receive_network_packets)
{

packet = receive_packet();

if (packet.id <= last_packet_id)
{
// the sender might not have received
// an acknowledgment that we received
// this packet, so better send it again
send_acknowledgment(packet.id);
}
else if (packet.id == last_packet_id + 1)
{
// this is the one we're after
last_packet_id = packet.id;
// let the other end know we got it
send_acknowledgment(packet.id);
// do whatever we want
do_something_funky(packet);
}
else /*packet.id > last_packet_id + 1*/
{
// whoops, we must have missed one.
// who cares then about this? the
// sender will figure out we haven't
// received a packet when they don't
// get our acknowledgment within a
// certain length of time, and will
// re-send the packets we haven't
// received yet at that point. We
// just have to wait :)
}

}