Getting more the one client going.

Hey, I am trying to make a server that can handle multiple clients at once. Only thing is, I am not sure how do go about coding it fully… I have some code or the server itself judt not the the handling of more then one client. I had the idea to let the client send their ip and have the server store it so that it shows the IP is log on and is using so and so thread of the server, but wasnt sure on how to go about coding it that. Anyone have a idea on about doing that? - Some code helps better then just trying to say it.

Edit: After some looking it up on the web I saw something call threads for python… if they are the same as with c++ I never really understood them and even looking on the web now at them with python they seem soo crazy XD. " thread.start_new_thread(threadname,(2,))" I guess I can call that to start up a need handle for each new ip address that comes in but still trying to figure out how it works.

no!

Dont use threads. There are some networking samples on the forums for you to look at - including a mmorpg framework.

Good ^.^ But at the same time I have to ask why not use threads?

Only problem with looking at someone elses is code is they make it more pro to their app so when I look at other people’s network code it seems to be using much more code then it would seem to take really.

Not really making a mmorpg, I know it takes alot of programming and everything… more or less a little place where my friends can meet up at and chat, but you know not cap limit. I know I can set it up to have more then one user and everything its just setting it up to be uncap the problem.

Why not threads. Maybe you get your answer here: discourse.panda3d.org/viewtopic.php?t=4778

And perhaps the following snippet may help (do not use it like this because the protocol is nonsens, there is no application layer at all):

import sys
import socket
import random
import time
import select

PORT = 1234

def client():
	client = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
	client.connect(("127.0.0.1", PORT))
	time.sleep(1.0)
	client.send("Dice " + str(random.randint(1, 6)))
	time.sleep(1.0)
	print client.recv(4096),
	client.close()

def server():
	server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
	server.setblocking(0)
	server.bind(("", PORT))
	server.listen(5)
	clients = []

	while True:
		# a timeout allows to press Ctrl+C
		ready = select.select([server] + clients, [], [], 0.5)[0]

		if server in ready:
			client, (address, port) = server.accept()
			clients.append(client)
			ready.remove(server)
			print "Connect", client.getpeername()

		answer = ""

		for client in ready:
			message = client.recv(4096)
			if len(message) == 0:
				clients.remove(client)
				print "Disconnect", client.getpeername()
			else:
				answer += client.getpeername()[0] + ":" + message + "\n"

		for client in clients:
			client.send(answer)

if len(sys.argv) > 1:
	if sys.argv[1] == "server":
		print "Server"
		server()
	elif sys.argv[1] == "client":
		print "Client"
		client()

Start the application in two or more shells:

Shell 1: myapplication.py server
Shell 2: myapplication.py client
Shell 3: myapplication.py client

IMHO try to stick with TCP and remember that TCP is a stream. You need a marker to reassemble your packets correctly. BTW the MCORPG GuildWars does only use TCP.

Thanks, i’ll have a look at it and try to work with it in my code, I guess I should update my code to use TCP instead of the UDP I have setup right now. From what I have look at it, I can setup both with how this looks. Making the UDP used for when the “toon” moves and other fast data that needs to be send.

udp is fine as long as your client/server can handle packets in wrong order, and as long as you make sure that important packages arrive.
in simplest case just put those important packages into a list, and resend them until it receives a message from the other end that the packet was successfully received.

As ThomasEgi said, but with other words, with UDP you have to redo all the things that TCP already does for you. If you really know what you do, then UDP may be good for you. If order doesn’t matter and you don’t care if you loose packets, then UDP may as well be your choice.

Will yea, TCP vs UDP is speed/size witch comes down to how the 2 dos packet management, UDP sends stuff and doesnt care if it gets there or not. While TCP waits and resends if it doesnt. Why I think TCP should be used for logons and other important data, UDP can be used to send key commands that needs to go to the server perty fast. (aka moving around or jumping)

I have not done alot of testing of the both (cus I dont have 2 PC to test on fully, cus they are lan connections) so i’m not 100% sure UDP is that bad compare to TCP in having packets in the wrong order or missing.

Edit: Haha my idea was sorta right, after some seraching on the web I came by this "Unfortunately there is no mitigation for the reliability of TCP. If a packet is dropped, then no new packets will be accepted until the missing packet arrives. This can cause a great amount of perceived lag. Have you ever played a game where you are moving your sprite, and then all of a sudden you stop moving, so you keep hitting the forward button. Then, all of the sudden your sprite bursts into a fast-forward sprint. This is because the movement packets were sent with TCP. "

This is how my current code look/works (it doesnt have what you showed me yet) It was only setup for 1 user. Haha and you can see why when you look at someone else network code its alot bigger then whats really there=)

#Server program

from socket import *
import threading
import time


# Set the socket parameters
host = ""
port = 21568
port2 = 21567
buf = 1024
buf2 = 1024
addr = (host,port)

# Create socket and bind to address
UDPSock = socket(AF_INET,SOCK_DGRAM)
UDPSock.bind(addr)

data,addr = UDPSock.recvfrom(buf)
client = data
addr2 = (client, port2)
data,addr = UDPSock.recvfrom(buf)
if data == "Hey you there?":
  data = "Yes"
  (UDPSock.sendto(data,addr2))
  print client, " trying to log on."
else:
  print "unknow error 200"
data,addr = UDPSock.recvfrom(buf)
name = data
data2 = "Users/" + name + ".txt"
f = open(data2,"r")
lineList = f.readlines()
f.close()
name2 = "Name: " + name + "\n"
if name2 == lineList[0]:
  data,addr = UDPSock.recvfrom(buf)
  password = "Password: " + data + "\n"
  if password == lineList[1]:
    print name,"log on."
    data = lineList[2].strip()
    (UDPSock.sendto(data,addr2))
    data = lineList[3].strip()
    (UDPSock.sendto(data,addr2))
    data = "===Welcome==="
    (UDPSock.sendto(data,addr2))
    while 1:
      data,addr = UDPSock.recvfrom(buf)
      f = open("myfile.txt", 'r+')
      for l in f:
        l + "\n"
      msg = "received: " + time.ctime() + ": " + data + "\n"
      f.write(msg)
      f.close()
      print "\nReceived message '", msg,"'"       
  else:
    print "Wrong."
else:
  print "No one by that name."

# Close socket
UDPSock.close()

thats exactly why UDP is the choice if it has to go fast. and if the receiver sends an packet back telling the sender that his packet arrived you can even make a simple reliable system by brute forcing packets until they arrive.
your receivers can also drop late packages in case they arrive late.

many many onlinegames are doing it this way. including most ego-shooteres started with… i think quake1 or so was the first one introducing this technique. but works great even today.

wanted to add. i tried both, tcp and udp. had no problems with either of them as long as the connection is somewhat stable. if the connection tends to drop packages ( had a bad lan-cable for some time) then udp wins. since you dont have the TCP-lags when it waits for response. with this broken cable i had a packetloss of roughly 60% so almost a wrost-case but it still worked wuite well with udp.

also note. panda has a nice tcp based mid-level networking system offering nice things like detection of broken connections etc. about the udp part of pandas building network no idea. but sockets work fine.

just in case. if you think about using pickle… DONT.
a ways more secure way to serialize python standart types is to use rencode.
once found it on a python cookbook page. works quite well and features nice thing as compression of the data using zlib (to save traffic), unicode strings, and dictionaries and and and. you can get it here.
http://home.arcor.de/positiveelectron/files/project-files/rencode.py

You can write a perfect protocol with UDP as you can write a perfect engine with C++. But there is a reason why we use Panda3D. That is the same reason why I try to stick with TCP.

If you only have one Computer maybe download virtualbox.org/ and install a second OS.

well its not like panda is not a c++ engine.
and about the choice between TCP and UDP. both have major advantages and disadvantages. so you should choose it accordingly to your needs. there is no answer like “tcp/udp is better”
it really depends on the thing you want to do with it.
if you only use it on local networks, or even only loopback it doesnt really matter that much. but for “true” online applications choosing the right thing,. or the right combination is important

You can replace TCP/UDP with Panda3D/“Your Own C++ Engine” in your post. Both have major advantages and … you got it … But TCP is easier to use than UDP. Ever wondered why TCP implementations are x times larger than UDP. They still tweak on TCP in linux e.g. now and then to get better performance, there is an enormous amount of knowledge in a TCP implementation.
Maybe I’ve to admit that I use Panda3D because I can program in Python. No Python no Panda3D is true for me.

Azraiyl:
Na, C++ is good but python getting there or is there compare to c++, I love C++ but they could change some of the ways python does it a little better but at the same time thos simple changes make c++ good too XD Also thanks for the link i’ll take a look at it.

Yea your right, TCP is easier to use compare to UDP cus they’re less bugs that come from TCP compare to UDP (aka packet lost, and a open port). Thats why TCP bigger cus they take in a time snap and packet name into itself. You can do this for UDP or just a time snap like a newer game did… cant remember what the game was, I think it was quake 3, they went full UDP and for a FPS. Its the best for it cus all the data is fast and never ending/doesnt matter fully on where you are all the time and as ThormasEgi help me see is “60%” of the packets sent were lost it would cus lag cus the TCP would want all thos packets back making newer ones wait while UDP can keep sending a newer pos.

Ahaha, at the same time using TCP can be used as a cheat … O.o; wow XD haha=) my evil mind was thinking bad thoughts x.x;

ThomasEgi:
Yea your right, there is no better tcp/udp, just how you use them with your app.

Also, I maybe wrong about this, but TCP is used for communication between 2 computers. Or like yelling at your kids to clean their rooms =) While UDP is used to send fast changing data that just needs to get down to the other computer no matter what. Or like you talking on the phone to another person, you dont want the call to be drop du to waiting for a packet.

Edit: I have them flip around lol. -Also changed for another post.

I program C++ too, but maybe one year ago I started to hate it more and more. In C++ I have to care about the language, in Python I can solve my problems. Ever tried to solve an error around a Metatemplate in C++, horrible. There are tons of books (e.g. from Scott Meyers or Herb Sutter), out there which only deals with the problems you can introduce with C++, problems that never will exist in Python. Enough off topic and ranting, hope you get your network layer done :slight_smile: