0

So far, I have been working with Sockets. One socket for sending and receiving. I've been told that that is stupid, however I was not able to find the correct way to use socketpairs on client and server from ground up. I will give my current way, and hope someone could tell me how to do socketpairs with this. Using TCP by the way.

#client
import socket

my_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
ip =  "127.0.1.1"
port = 22222
my_socket.connect((ip, port))
#server
import socket
import multiprocessing

s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
ip_address = socket.gethostbyname(hostname)
port = 22222
s.bind((ip_address, port))
s.listen(20)

connections=[]
connection_threads=[]
while True:
    clientsocket, address = s.accept()
    #does this create a new socket for every incoming connection by the way?
    new_client = client.Client(address, clientsocket)
    connections.append(new_client)
    new_process = multiprocessing.Process(target=client_butler.connect_client, args=(new_client,))
    new_process.start()
    connection_threads.append(new_process)

My end goal would be that the server has one socketpair for every client. I know that this is probably not good implementation as it is completely ignoring errorhandling and so on, but I will look at that in the future as all I am trying to do is me self teaching this. So the question is, how would I transform this into working with socketpairs?

Problems I have:

  • How do I connect the socketpair as in my client via my_socket.connect?
  • If I just connect both sockets individually, how do I 'reassemble' the pair in the server
  • Am I even doing this correctly, or is this the completely wrong approach?

Also: I checked this out, but even if I could copy the code and it would work I wouldn't know why it would work, which isn't what I want, I don't want this to work I'd also like to learn from this.

Thanks!

Maritn Ge
  • 997
  • 8
  • 35
  • 1
    Since connections are bidirectional, its common to just use one. Its also common to have one connection for commands and one or more connections for data. – tdelaney Dec 25 '20 at 16:04
  • @SteffenUllrich [this](https://stackoverflow.com/a/65207335/12338762) answer to one of my questions basically is what gave me the idea, I am not sure if I misunderstood his answer, but it seemed to me like i should have 2 sockets to send and to listen. – Maritn Ge Dec 25 '20 at 16:05
  • 1
    @MaritnGe: send and listen are two different sockets, send and receive not. Listen is just to accept new connections, not to exchange actual data. – Steffen Ullrich Dec 25 '20 at 16:06
  • @SteffenUllrich so... listen is waiting for connections and receive is getting data? So my server would have one socket waiting for connections, listening, and one socket for every client? – Maritn Ge Dec 25 '20 at 16:08
  • 1
    https://stackoverflow.com/questions/64214231/why-do-i-need-socketpair-when-i-have-socket-with-af-unix – President James K. Polk Dec 25 '20 at 16:10
  • 1
    @MaritnGe: exactly, one server socket for listen+accept and each accept returns a new connected socket for the actual data exchange with the connected client. – Steffen Ullrich Dec 25 '20 at 16:10
  • @SteffenUllrich amazing, thank you! what then is the point of socketpairs? – Maritn Ge Dec 25 '20 at 16:14
  • 1
    @MaritnGe - That answer was for a program communicating with itself (and is commonly used with child processes). In a client / server app, there are a pair of sockets - one connected in the client and one accepted in the server. Within a single app, `socket.socketpair` does the same thing but in the single process. `socketpair` is a shortcut for the listen/connect/accept handshake and bypasses the TCP stack altogether. – tdelaney Dec 25 '20 at 16:17
  • 1
    @MaritnGe: [socketpair](https://man7.org/linux/man-pages/man2/socketpair.2.html) is used for inter-process communication. The parent process creates a socketpair, forks the child process and then each one keeps on side of this socket pair (i.e. one socket) open to communicate with the other. – Steffen Ullrich Dec 25 '20 at 16:17
  • @SteffenUllrich wait, can I use socketpairs for multiprocessing? – Maritn Ge Dec 25 '20 at 16:18
  • 1
    Yes, you can use socketpair for multiprocessing on unix-like systems. `socketpair` creates file descriptors which are available to a subprocess that forks after the socketpair call has been made. The parent uses one of the sockets while the child uses the other. Your code decides which uses which. – tdelaney Dec 25 '20 at 16:19

1 Answers1

0

Referenced from Computer Networking: A Top-Down Approach, 7th Edition:

client.py:

from socket import *


serverName = "127.0.0.1"
serverPort = 12000

clientSocket = socket(AF_INET, SOCK_STREAM)
clientSocket.connect((serverName, serverPort))

sentence = input('Input lowercase sentence: ')
clientSocket.send(sentence.encode())

modifiedSentence = clientSocket.recv(1024)

print('From Server: ', modifiedSentence.decode())

clientSocket.close()

server.py

from socket import *

serverPort = 12000
serverSocket = socket(AF_INET, SOCK_STREAM)

serverSocket.bind(('', serverPort))
serverSocket.listen(1)

print('The server is ready to receive')

while True:
    connectionSocket, addr = serverSocket.accept()
    sentence = connectionSocket.recv(1024).decode()
    capitalizedSentence = sentence.upper()
    connectionSocket.send(capitalizedSentence.encode())
    connectionSocket.close()

SiAce
  • 357
  • 3
  • 15
  • 1
    But where are the socketpairs here? someone told me i shouldn't use the same socket to send/listen – Maritn Ge Dec 25 '20 at 16:01
  • 1
    @MaritnGe - You can't send or receive anything on a listen sockets, but you can send _and_ receive on the accepted socket. – tdelaney Dec 25 '20 at 16:05
  • @MaritnGe, I am not sure what do you want, but usually there is only one port for listening to connections, and once the there is connection, the server will create another port for each connections for exchanging data. – SiAce Dec 25 '20 at 16:08