Socket Help

Hello

For the past while, I have been trying to make an online game using TCP or UDP Sockets. For some reason, it will not work, even though according to all tutorials and even gameblender examples, it should work. I have a grasp of what I am doing wrong… If anyone knows how to get TCP or UDP going on properly, can you give me a tip?


###### Server

import socket

host = ""
port =  3006

sock = socket.socket(socket.AF_INET, socket.STREAM)
sock.bind((host, port))

sock.listen(1)
client, addr = sock.accept() # Crash point

dat_send = "Test String"

client.send(dat_send)

###### Client ######

import socket

host = "192.168.1.103"
port =  3006

sock = socket.socket(socket.AF_INET, socket.STREAM)
sock.connect((host, port))

data = sock.recv(1024)

print data


Whenever I run either script, blender freezes. On the Server Script I narrowed it down to “sock.accept()”. According to #python on irc, the freezing is normal, and is happening because there is no client. They also mentioned something about a “select()” thingy that is supposed to tell wether or not a client is there. Although, #python became tiresome of my newbie-ism, and they don’t like me anymore :frowning: . I don’t understand the “select()” thing. I have searched the internet like crazy, looking for any sort of working example of python sockets, none of the examples worked.

Here is a tut on the select() thingy… I don’t understand it, but it is suposedly the solution to my sockets. Can anybody help me understand it? Thanks in advanced,

Chaser


If you've understood the preceeding, you already know most of what you need to know about the mechanics of using sockets. You'll still use the same calls, in much the same ways. It's just that, if you do it right, your app will be almost inside-out.

In Python, you use socket.setblocking(0) to make it non-blocking. In C, it's more complex, (for one thing, you'll need to choose between the BSD flavor O_NONBLOCK and the almost indistinguishable Posix flavor O_NDELAY, which is completely different from TCP_NODELAY), but it's the exact same idea. You do this after creating the socket, but before using it. (Actually, if you're nuts, you can switch back and forth.)

The major mechanical difference is that send, recv, connect and accept can return without having done anything. You have (of course) a number of choices. You can check return code and error codes and generally drive yourself crazy. If you don't believe me, try it sometime. Your app will grow large, buggy and suck CPU. So let's skip the brain-dead solutions and do it right.

Use select.

In C, coding select is fairly complex. In Python, it's a piece of cake, but it's close enough to the C version that if you understand select in Python, you'll have little trouble with it in C.


    ready_to_read, ready_to_write, in_error = \\
                   select.select(
                      potential_readers, 
                      potential_writers, 
                      potential_errs, 
                      timeout)
You pass select three lists: the first contains all sockets that you might want to try reading; the second all the sockets you might want to try writing to, and the last (normally left empty) those that you want to check for errors. You should note that a socket can go into more than one list. The select call is blocking, but you can give it a timeout. This is generally a sensible thing to do - give it a nice long timeout (say a minute) unless you have good reason to do otherwise.

In return, you will get three lists. They have the sockets that are actually readable, writable and in error. Each of these lists is a subset (possbily empty) of the corresponding list you passed in. And if you put a socket in more than one input list, it will only be (at most) in one output list.

If a socket is in the output readable list, you can be as-close-to-certain-as-we-ever-get-in-this-business that a recv on that socket will return something. Same idea for the writable list. You'll be able to send something. Maybe not all you want to, but something is better than nothing. (Actually, any reasonably healthy socket will return as writable - it just means outbound network buffer space is available.)

If you have a "server" socket, put it in the potential_readers list. If it comes out in the readable list, your accept will (almost certainly) work. If you have created a new socket to connect to someone else, put it in the ptoential_writers list. If it shows up in the writable list, you have a decent chance that it has connected.

One very nasty problem with select: if somewhere in those input lists of sockets is one which has died a nasty death, the select will fail. You then need to loop through every single damn socket in all those lists and do a select([sock],[],[],0) until you find the bad one. That timeout of 0 means it won't take long, but it's ugly.

Actually, select can be handy even with blocking sockets. It's one way of determining whether you will block - the socket returns as readable when there's something in the buffers. However, this still doesn't help with the problem of determining whether the other end is done, or just busy with something else.

Look at Multiplayer and Multiplayer2

None of those examples work. Blender freezes when it gets to “s.accept()” because the socket is trying to accept the client connection before the client is there or something ( According to #python ). the “select()” thing is supposed to check if there is a client there, then it will work. Problem is, i don’t understand the “select()” thing.

Chaser,

have you tried UDP version of examples - it has no accept(), so it’s not freezing at all.
You should not worry on select() - it will not work in Blender anyway - because select() waits for incoming comunication and blocks Python script. In GameBlender there should Python scripts finish quick, because they run in the same thread as main game loop and block game from running.

how i loath u chaser

If none of the examples work, maybe it’s something about your connection or your computer, like a firewall or something. I don’t know anything about it, though.

Sounds like a question for saluk.

I think he uses the Twisted networking framework for CDO. It’s something you might want to take a look at.

Hey guys, this is an old thread that was dug up by a newcomer. I imagine the issue has been resolved or abandoned by now. Remember to check the dates and watch out for low post counts.

Hmm the downside of a newcomer trying to find the help that he needs via the search option, I have done that a thousand times already in the hopes of finding an answer to many questions.