This repository has been archived by the owner on Aug 2, 2023. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 68
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
d275a9d
commit 8062503
Showing
7 changed files
with
184 additions
and
83 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,38 +1,107 @@ | ||
from __future__ import absolute_import | ||
|
||
from collections import namedtuple | ||
import socket | ||
|
||
import ptvsd.wrapper as _ptvsd | ||
|
||
def connect(host, port): | ||
"""Return (client, server) after connecting. | ||
|
||
If host is None then it's a server, so it will wait for a connection | ||
on localhost. Otherwise it will connect to the remote host. | ||
def create_server(address): | ||
"""Return a server socket after binding.""" | ||
host, port = address | ||
return _ptvsd._create_server(port) | ||
|
||
|
||
def create_client(): | ||
"""Return a new (unconnected) client socket.""" | ||
return _ptvsd._create_client() | ||
|
||
|
||
def connect(sock, address): | ||
"""Return a client socket after connecting. | ||
If address is None then it's a server, so it will wait for a | ||
connection. Otherwise it will connect to the remote host. | ||
""" | ||
return _connect(sock, address) | ||
|
||
|
||
def bind(address): | ||
"""Return (connect, remote addr) for the given address. | ||
"connect" is a function with no args that returns (client, server), | ||
which are sockets. If the host is None then a server socket will | ||
be created bound to localhost, and that server socket will be | ||
returned from connect(). Otherwise a client socket is connected to | ||
the remote address and None is returned from connect() for the | ||
server. | ||
""" | ||
sock = socket.socket( | ||
socket.AF_INET, | ||
socket.SOCK_STREAM, | ||
socket.IPPROTO_TCP, | ||
) | ||
sock.setsockopt( | ||
socket.SOL_SOCKET, | ||
socket.SO_REUSEADDR, | ||
1, | ||
) | ||
host, _ = address | ||
if host is None: | ||
addr = ('127.0.0.1', port) | ||
sock = create_server(address) | ||
server = sock | ||
server.bind(addr) | ||
server.listen(1) | ||
sock, _ = server.accept() | ||
connect_to = None | ||
remote = sock.getsockname() | ||
else: | ||
addr = (host, port) | ||
sock.connect(addr) | ||
sock = create_client() | ||
server = None | ||
return sock, server | ||
connect_to = address | ||
remote = address | ||
|
||
def connect(): | ||
client = _connect(sock, connect_to) | ||
return client, server | ||
return connect, remote | ||
|
||
|
||
def close(sock): | ||
"""Shutdown and close the socket.""" | ||
sock.shutdown(socket.SHUT_RDWR) | ||
sock.close() | ||
|
||
|
||
class Connection(namedtuple('Connection', 'client server')): | ||
"""A wrapper around a client socket. | ||
If a server socket is provided then it will be closed when the | ||
client is closed. | ||
""" | ||
|
||
def __new__(cls, client, server=None): | ||
self = super(Connection, cls).__new__( | ||
cls, | ||
client, | ||
server, | ||
) | ||
return self | ||
|
||
def send(self, *args, **kwargs): | ||
return self.client.send(*args, **kwargs) | ||
|
||
def recv(self, *args, **kwargs): | ||
return self.client.recv(*args, **kwargs) | ||
|
||
def makefile(self, *args, **kwargs): | ||
return self.client.makefile(*args, **kwargs) | ||
|
||
def shutdown(self, *args, **kwargs): | ||
if self.server is not None: | ||
self.server.shutdown(*args, **kwargs) | ||
self.client.shutdown(*args, **kwargs) | ||
|
||
def close(self): | ||
if self.server is not None: | ||
self.server.close() | ||
self.client.close() | ||
|
||
|
||
######################## | ||
# internal functions | ||
|
||
def _connect(sock, address): | ||
if address is None: | ||
client, _ = sock.accept() | ||
else: | ||
sock.connect(address) | ||
client = sock | ||
return client |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.