In this line -> tcpSerSock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) what is the first 'socket' after the '=' sign, is that refering to a socket class making tcpSerSock an object or just to a module called socket?

After reading the documentation I see that socket.accept returns a connection and an address pair, but it doesn't say what is returns them in, a list or a tuple or something else? So how would this line work
-> tcpCliSock, addr = tcpSerSock.accept() ?

And can anyone tell me why the following two server/client programs are not working on my system (Linux)? When I run the client it says -> tcpCliSock.connect(ADDR) -> OSError: [Errno 101] Network is unreachable

Client

#!/usr/bin/python3

from socket import *

HOST = '127.0.0.1' # or 'localhost'
PORT = 21567
BUFSIZ = 1024
ADDR = (HOST, PORT)

tcpCliSock = socket(AF_INET, SOCK_STREAM)
tcpCliSock.connect(ADDR)

while(True):
    data = input('> ')
    if not data:
        break
    tcpCliSock.send(data)
    data = tcpCliSock.recv(BUFSIZ)
    if not data:
        break
    print(data.decode('utf-8'))

tcpCliSock.close()

Server

#!/usr/bin/python3

from socket import *
from time import ctime

HOST = ''
PORT = 21567
BUFSIZ = 1024
ADDR = (HOST, PORT)

tcpSerSock = socket(AF_INET, SOCK_STREAM)
tcpSerSock.bind(ADDR)
tcpSerSock.listen(5)

while True:
    print('waiting for connection...')
    tcpCliSock, addr = tcpSerSock.accept()
    print('...connected from:', addr)

    while True:
        data = tcpCliSock.recv(BUFSIZ)
        if not data:
            break
        tcpCliSock.send('[%s] %s' % (bytes(ctime(), 'utf-8'), data))

    tcpCliSock.close()
tcpSerSock.clsoe()

In answer to your questions:
1: I think the first socket in socket.socket is the package name and the second one refers to the socket class which resides in that package.

2: I don't know, but it does! Heh heh!
No, seriously... It is possible for Python functions to return more than one value. I think it's a Tuple that gets returned.

3: Reasons the client's not working? Hmmm.... You did make sure you started running the server before running the client didn't you? :P

Actually, I just tried running your client without the server on my *nix laptop and got a completely different error to the one you are seeing. So I don't think that is your problem.
Running the server and then running the client worked for me, without any errors.

'Network is unreachable' Sounds like the connection to localhost cannot be established. Is it possible that something like a firewall rule on your machine is preventing the client from connecting? Or have you accidentally disabled networking in the network manager applet? IDK. Could be any number of things!

Your client program works for me, right up until I send some data to the server. Then the client bombs out with an error:
TypeError: str does not support buffer interface

As this is python3, at line 17 of client.py, you need to encode the data to convert it to bytes:
tcpCliSock.send(data.encode())
You also need to decode the data when it is received by the server too. So at line 21 of server.py:
data = tcpCliSock.recv(BUFSIZ).decode()
And also at line 24 of server.py, another encode is in order:
tcpCliSock.send(('[%s] %s' % (bytes(ctime(), 'utf-8'), data)).encode())
That should fix those problems!

Edited 2 Years Ago by JasonHippy

Thank, I made those changes and all though the errors are gone after pressing RETURN it goes back to the prompt and I don't get any output.

I also figured out the connection issue, I chagned '172.0.0.1' to 'localhost' and now it works fine, I know that doesn't make any sence but go figure.

One last thing, what is all this encode/decode stuff? Thanks, I appreciate your help.

Basically, as far as I understand it, there are two types of string in Python3: Byte-strings and Unicode-strings.

The sockets in Python3 aren't aware of the different string encodings, so they only use raw byte-strings. So when passing a unicode string via a socket, you need to convert it to a byte-string using .encode().

Likewise, when receiving a byte-string from a socket to put into a string variable, you need to convert it to a unicode string using .decode()

Not sure why you're having problems there. Both programs work fine for me! I ran the server and the client, typed a couple of messages and then broke out of both programs with ctrl-c.
Here's the output I get from the server:

$ ./server.py
waiting for connection...
...connected from: ('127.0.0.1', 45060)
waiting for connection...
^CTraceback (most recent call last):
  File "./server.py", line 17, in <module>
    tcpCliSock, addr = tcpSerSock.accept()
  File "/usr/lib/python3.2/socket.py", line 132, in accept
    fd, addr = self._accept()
KeyboardInterrupt

And here's what was in the terminal running the client:

$ ./client.py 
> hello
[b'Fri Jan 17 00:57:36 2014'] hello
> This seems to work!
[b'Fri Jan 17 00:57:51 2014'] This seems to work!
> ^CTraceback (most recent call last):
  File "./client.py", line 14, in <module>
    data = input('> ')
KeyboardInterrupt

So the client correctly sends data to the server and the server responds by sending a string back to the client.

Thanks, got it working. I didn't have all my '()' symbols inserted correctly. One last thing, what BUFSIZ all about, when and why do I need to wory about bufsize, what is it?

This question has already been answered. Start a new discussion instead.