-
Notifications
You must be signed in to change notification settings - Fork 4
/
Copy pathconnection.py
156 lines (128 loc) · 5.8 KB
/
connection.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
import argparse
import threading
import socket
import queue
import enum
DEFAULT_LOCAL_IP_ADDRESS = '0.0.0.0'
DEFAULT_LOCAL_PORT_NUMBER = 8888
DEFAULT_REMOTE_IP_ADDRESS = 'localhost'
DEFAULT_REMOTE_PORT_NUMBER = 9999
DEFAULT_BUFFER_SIZE = 1024
class LocalStatus(enum.Enum):
SERVER_INITIALIZED = 'Local socket initialized.'
SERVER_LISTENING = 'Local socket listening.'
SERVER_SHUTDOWN = 'Local socket shutdown.'
class RemoteStatus(enum.Enum):
HANDSHAKE_INITIALIZED = 'Handshake initialized.'
HANDSHAKE_SUCCESSFUL = 'Handshake successful.'
class Connection:
def __init__(self, local_ip_address, local_port_number, remote_ip_address,
remote_port_number, buffer_size):
self.local_socket = None
self.local_ip_address = local_ip_address
self.local_port_number = local_port_number
self.remote_ip_address = remote_ip_address
self.remote_port_number = remote_port_number
self.buffer_size = buffer_size
self.local_queue = queue.Queue()
self.local_status = None
self.local_thread = threading.Thread(name='localThread',
target=self.open_local_socket)
self.local_thread.daemon = True
self.local_thread.start()
self.remote_status = None
self.handshake_thread = threading.Thread(name='handshakeThread',
target=self.initiate_handshake)
self.handshake_thread.daemon = True
self.handshake_thread.start()
def initiate_handshake(self):
self.remote_status = RemoteStatus.HANDSHAKE_INITIALIZED
print (self.remote_status)
while True:
remote_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
remote_socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
try:
remote_socket.connect((self.remote_ip_address, self.remote_port_number))
remote_socket.send('SYN\n')
if remote_socket.recv(self.buffer_size) == 'ACK\n':
remote_socket.send('SYN-ACK\n')
remote_socket.shutdown(socket.SHUT_WR)
remote_socket.close()
self.remote_status = RemoteStatus.HANDSHAKE_SUCCESSFUL
print (self.remote_status)
else:
pass
break
except socket.error:
continue
def send(self, message):
remote_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
remote_socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
try:
remote_socket.connect((self.remote_ip_address, self.remote_port_number))
print ('Remote socket sent:'), message
remote_socket.send(message + '\n')
remote_socket.shutdown(socket.SHUT_WR)
remote_socket.close()
except socket.error:
pass
def get_message(self):
if not self.local_queue.empty():
return self.local_queue.get()
else:
return None
def open_local_socket(self):
self.local_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
self.local_socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
self.local_socket.bind((self.local_ip_address, self.local_port_number))
self.local_socket.listen(1)
self.local_status = LocalStatus.SERVER_LISTENING
print (self.local_status)
while True:
try:
connection, address = self.local_socket.accept()
message = connection.recv(self.buffer_size)
if message == 'SYN\n':
connection.send('ACK\n')
else:
print ('Local socket received:'), message.rstrip()
self.local_queue.put(message)
except socket.error:
break
def close_server_socket(self):
try:
self.local_socket.shutdown(socket.SHUT_RD)
self.local_socket.close()
self.local_status = LocalStatus.SERVER_SHUTDOWN
print (self.local_status)
except socket.error:
pass
self.local_thread.stop = True
self.handshake_thread.stop = True
def main(local_ip_address, local_port_number,
remote_ip_address, remote_port_number,
buffer_size):
return Connection(local_ip_address, local_port_number,
remote_ip_address, remote_port_number,
buffer_size)
if __name__ == '__main__':
parser = argparse.ArgumentParser()
parser.add_argument('-lip', '--localIPAddress', help='local IP address',
required=False, default=DEFAULT_LOCAL_IP_ADDRESS)
parser.add_argument('-lpn', '--localPortNumber', help='local port number',
required=False, type=int, default=str(DEFAULT_LOCAL_PORT_NUMBER))
parser.add_argument('-rip', '--remoteIPAddress', help='remote IP address',
required=False, default=DEFAULT_REMOTE_IP_ADDRESS)
parser.add_argument('-rpn', '--remotePortNumber', help='remote port number',
required=False, type=int, default=str(DEFAULT_REMOTE_PORT_NUMBER))
parser.add_argument('-bs', '--buffer_size', help='buffer size',
required=False, type=int, default=str(DEFAULT_BUFFER_SIZE))
args = parser.parse_args()
print ('localIpAddress:'), args.localIPAddress
print ('localPortNumber:'), args.localPortNumber
print ('localIpAddress:'), args.remoteIPAddress
print ('localPortNumber:'), args.remotePortNumber
print ('buffer_size:'), args.buffer_size
main(args.localIPAddress, args.localPortNumber,
args.remoteIPAddress, args.remotePortNumber,
args.buffer_size)