We help IT Professionals succeed at work.

Not Sure Which Client/Server 'Service' To Use

tdk_man
tdk_man asked
on
279 Views
Last Modified: 2011-09-20
Not being too sure of what I'm doing, I'd like to first apologise if my question is vague or stupid.

Basically, I want to write client and server apps (in Delphi 5) where the server allows multiple clients to log on at the same time.

Two of the clients can then choose to play a game against each other via the server, so the server would need to send the same data to just those two clients (only text and the occasional jpg file). All the 'gaming side' would be controlled by the clients and data passed back to the server.

Would this be done best with an ftp, http or UDP client/server setup (if it matters)?

I've spent months experimenting with doing this - with no success. I can use the Delphi native socket components to create the client/server connection, but haven't been able to figure out which of the current connections on the server is which. For example, my server app will  tell me that there are 4 active connections, but I can't seem to find out which one is Bob and which one is Dave so I can 'link' them together to send data just to them.

If I could attach an IP address to each connection, it would help, but Socket.RemoteAddress just causes an error when I try to use it.

The only option seems to be to send the same data to *all* four connections and have the client end ignore info not meant for them. This seems to be a lot of wasted bandwidth to me.

Can anyone suggest the best way to go about doing something like this please, or point me to some resources on the net which cover this in Delphi?

Many thanks...

BC
Comment
Watch Question

CERTIFIED EXPERT
Commented:
This one is on us!
(Get your first solution completely free - no credit card required)
UNLOCK SOLUTION

Author

Commented:
"just lookup the correct server socket and send the message"

That's the bit that doesn't seem possible to do - or at least I can't figure it out. :)

Also, a jpg isn't a 'message', so you can't use the send text function!

BC

Commented:
Could we see the bit of code for :-

   "but Socket.RemoteAddress just causes an error when I try to use it."

so that we can get practical!

>>Also, a jpg isn't a 'message', so you can't use the send text function!

No, what this means is that between server and client one need a protocol. This is simply a fixed message structure enabling you to do things simply and reliably.

Each message should start with a four-byte length, a fixed portion, say a 1 byte command (1=text comming, 2=jpeg comming) and a variable bit. You then write routines to send and receive complete messages. If you use something like Indy there are routines available for sending/receiving in this format. If not (you're using RAW sockets) don't forget that the message can get split and ONE call to recv won't necessarily get ALL the data at once.

Author

Commented:
Sorry for the delay in replying - the day after my last post, I lost my ADSL line and my telco only got it working again today! :(

@BigRat

"No, what this means is that between server and client one need a protocol. This is simply a fixed message structure enabling you to do things simply and reliably."

OK - that helps. I was asking in my original post, which 'service' (if that's the correct term) you should use when you want to send data of different types - such as jpg's and text. Am I right in thinking that 'service' and 'protocols' are interchangeable terms in this situation?

I've seen UDP (not sure what that is) and ftp which might do what I need, but was after a bit of advice on which would the best way to do it. Essentially, I need to have many clients connected to the server and link up pairs of them - sending the same data to each pair (this data would be selected randomly from a Paradox database, but the same data sent to each of the two 'linked' clients).

I have Indy9 installed, but haven't experimented with it at all until I find out which service I need to be using.

All trials so far have been with Delphi's native socket components. With them, I can write a server which lets multiple clients connect, but can't find a way to distinguish between two clients and send data to just them. As I said, the server tells me that there are 'x' clients connected, but there doesn't seem to be any way to 'link' two of them together (say connections 2 and 7)  and send the same data to both of them.

It seems you have to send the same data to every client connected - but this may well be a limitation of the Delphi socket components and I'll have to switch to Indy to get around this.

In the meantime, I'll see if I can knock together a bit of example code, but basically, according to the help, in the socket's OnAccept event handler, you should be able to use Socket.RemoteAddress to get the IP addy of the remote client. When I use this, I just get an error and the program won't run 'til I remove it.

However, even if it didn't error, I don't see any way to associate two IP addresses with two connections to send data to just those two IP address. But that may be down to my inexperience, stupidity, or a mixture of both! :)

Many thanks for your help though (I did say I was completely new to comms programming in Delphi and I'm finding it hard going).

BC
CERTIFIED EXPERT

Commented:
Explanation of UDP.  

When you send a UDP message it is sent to all ips on a segment where IP is sent only to one nic card(computer).

UDP is a broadcast and there is no connection to the receiving socket so it is much faster.  The problem is that there is no gaurantee that it was received by a given computer and also any computer may get the message more than once.

This is great for monitoring software, but not for your needs.  TCP/IP is the base protocol of choice.
CERTIFIED EXPERT

Commented:
If your wanting to build your own protocol then here is an overview.

Everymessage needs a header that is the same size for all messages
this header is 8 bytes.

TMyProtHeader = packed record //packed will not align to the OS registers so a word is 2 bytes not 4
   MsgNumber : Word;
   WhoIAm     : Word;
   MsgLength  : Integer;
end;


TMyProtMessage1 = packed record
  Header : TMyProtHeader;
  OtherInfoAsNeeded : Integer;
end;

so the receiving socket reads 8 bytes and casts it as a TMyProtHeader and determines how much more to read from the socket.  Then you place this msg at the end of a queue (TList will work).

A Timer or another thread is constantly checking the TList for messages and processing them.

Hope this gets you started.  This is the way we created our message queues for a very large custom call center in Singapore with 197 computers sending 10,000+messages a second.

Cheers
Commented:
This one is on us!
(Get your first solution completely free - no credit card required)
UNLOCK SOLUTION
CERTIFIED EXPERT

Commented:
In your thread to read the message so call the function to process the message in the same thread.  If you are receiving a lot of messages the queue will fill up and you will drop messages.  

You should place the message along with the Socket into a queue and allow another thread to process the messages and then do the socket.writemessage.  Otherwise the timeouts can kill you.

Commented:
kfoster11: Is your post, comming over an hour after mine, refering to me?

In an accepted TCP/IP connection one does not "drop" messages. The only place where things could get "dropped" is if the queue depth of the Listen is too low. On most systems this is around 200, I have only ever had problems on SCO Unix boxes where the *default* depth was 5. This does not mean five connections, but five *outstanding* (Ie: unprocessed) connections.

Gain unlimited access to on-demand training courses with an Experts Exchange subscription.

Get Access
Why Experts Exchange?

Experts Exchange always has the answer, or at the least points me in the correct direction! It is like having another employee that is extremely experienced.

Jim Murphy
Programmer at Smart IT Solutions

When asked, what has been your best career decision?

Deciding to stick with EE.

Mohamed Asif
Technical Department Head

Being involved with EE helped me to grow personally and professionally.

Carl Webster
CTP, Sr Infrastructure Consultant
Empower Your Career
Did You Know?

We've partnered with two important charities to provide clean water and computer science education to those who need it most. READ MORE

Ask ANY Question

Connect with Certified Experts to gain insight and support on specific technology challenges including:

  • Troubleshooting
  • Research
  • Professional Opinions
Unlock the solution to this question.
Join our community and discover your potential

Experts Exchange is the only place where you can interact directly with leading experts in the technology field. Become a member today and access the collective knowledge of thousands of technology experts.

*This site is protected by reCAPTCHA and the Google Privacy Policy and Terms of Service apply.

OR

Please enter a first name

Please enter a last name

8+ characters (letters, numbers, and a symbol)

By clicking, you agree to the Terms of Use and Privacy Policy.