一、socket概念
socket本质上就是在2台网络互通的电脑之间,架设一个通道,两台电脑通过这个通道来实现数据的互相传递。 我们知道网络 通信 都 是基于 ip+port 方能定位到目标的具体机器上的具体服务,操作系统有0-65535个端口,每个端口都可以独立对外提供服务,如果 把一个公司比做一台电脑 ,那公司的总机号码就相当于ip地址, 每个员工的分机号就相当于端口, 你想找公司某个人,必须 先打电话到总机,然后再转分机 。
建立一个socket必须至少有2端, 一个服务端,一个客户端, 服务端被动等待并接收请求,客户端主动发起请求, 连接建立之后,双方可以互发数据。
二、实例
1.sock_server_client.py:
#Author:Fred
import socket
client = socket.socket()
client.connect(('localhost',9999))
while True:
cmd = input(">>:").strip()
if len(cmd) == 0:continue
client.send(cmd.encode("utf-8"))
cmd_res_size = client.recv(1024) #接收命令结果的长度
print("命令结果大小;",cmd_res_size)
received_size = 0
received_data = b''
while received_size < int(cmd_res_size.decode()):
data = client.recv(1024)
received_size += len(data) #每次收到的有可能小于1024,所以必须用len判断
#print(data.decode())
received_data += data
else:
print("cmd res received done...",received_size)
print(received_data.decode())
client.close()
2.sock_server_ssh.py:
#Author:Fred
import socket,os
server = socket.socket()
server.bind(('localhost',9999))
server.listen()
while True:
conn,addr = server.accept()
print("new coon:",addr)
while True:
data = conn.recv(1024)
if not data:
print("客户端已断开")
break
print("执行指令:",data)
cmd_res = os.popen(data.decode()).read() #接收字符串,执行结果也是字符串
print("before send",len(cmd_res))
if len(cmd_res) == 0:
cmd_res = "cmd hs no output..."
conn.send(str(len(cmd_res.encode())).encode("utf-8")) #先发大小给客户端
conn.send(cmd_res.encode("utf-8"))
print("send done")
os.path.isfile()
os.stat("sock")
server.close()
三、sock_server基本方法
#Author:Fred
import socketserver
class MyTCPHandler(socketserver.BaseRequestHandler):
def handle(self):
while True:
try:
self.data = self.request.recv(1024).strip()
print("{} wrote:".format(self.client_address[0]))
print(self.data)
# if not self.data: #客户端断了
# print(self.client_address,"断开了")
# break
self.request.send(self.data.upper())
except ConnectionResetError as e:
print("err",e)
break
if __name__ == "__main__":
HOST, PORT = "localhost", 9999
# Create the server, binding to localhost on port 9999
server = socketserver.ThreadingTCPServer((HOST, PORT), MyTCPHandler)
# Activate the server; this will keep running until you
# interrupt the program with Ctrl-C
server.serve_forever()
四、socketserver方法
#Author:Fred
'''
class socketserver.BaseServer(server_address, RequestHandlerClass)
This is the superclass of all Server objects in the module. It defines the interface, given below, but does not implement most of the methods, which is done in subclasses. The two parameters are stored in the respective server_address and RequestHandlerClass attributes.
fileno()#返回文件描述符
Return an integer file descriptor for the socket on which the server is listening. This function is most commonly passed to selectors, to allow monitoring multiple servers in the same process.
handle_request()#处理单个请求
Process a single request. This function calls the following methods in order: get_request(), verify_request(), and process_request(). If the user-provided handle() method of the handler class raises an exception, the server’s handle_error() method will be called. If no request is received within timeout seconds, handle_timeout() will be called and handle_request() will return.
serve_forever(poll_interval=0.5)#
Handle requests until an explicit shutdown() request. Poll for shutdown every poll_interval seconds. Ignores the timeout attribute. It also calls service_actions(), which may be used by a subclass or mixin to provide actions specific to a given service. For example, the ForkingMixIn class uses service_actions() to clean up zombie child processes.
Changed in version 3.3: Added service_actions call to the serve_forever method.
service_actions()
This is called in the serve_forever() loop. This method can be overridden by subclasses or mixin classes to perform actions specific to a given service, such as cleanup actions.
New in version 3.3.
shutdown()
Tell the serve_forever() loop to stop and wait until it does.
server_close()
Clean up the server. May be overridden.
address_family
The family of protocols to which the server’s socket belongs. Common examples are socket.AF_INET and socket.AF_UNIX.
RequestHandlerClass
The user-provided request handler class; an instance of this class is created for each request.
server_address
The address on which the server is listening. The format of addresses varies depending on the protocol family; see the documentation for the socket module for details. For Internet protocols, this is a tuple containing a string giving the address, and an integer port number: ('127.0.0.1', 80), for example.
socket
The socket object on which the server will listen for incoming requests.
The server classes support the following class variables:
allow_reuse_address
Whether the server will allow the reuse of an address. This defaults to False, and can be set in subclasses to change the policy.
request_queue_size
The size of the request queue. If it takes a long time to process a single request, any requests that arrive while the server is busy are placed into a queue, up to request_queue_size requests. Once the queue is full, further requests from clients will get a “Connection denied” error. The default value is usually 5, but this can be overridden by subclasses.
socket_type
The type of socket used by the server; socket.SOCK_STREAM and socket.SOCK_DGRAM are two common values.
timeout
Timeout duration, measured in seconds, or None if no timeout is desired. If handle_request() receives no incoming requests within the timeout period, the handle_timeout() method is called.
There are various server methods that can be overridden by subclasses of base server classes like TCPServer; these methods aren’t useful to external users of the server object.
finish_request()
Actually processes the request by instantiating RequestHandlerClass and calling its handle() method.
get_request()
Must accept a request from the socket, and return a 2-tuple containing the new socket object to be used to communicate with the client, and the client’s address.
handle_error(request, client_address)
This function is called if the handle() method of a RequestHandlerClass instance raises an exception. The default action is to print the traceback to standard output and continue handling further requests.
handle_timeout()
This function is called when the timeout attribute has been set to a value other than None and the timeout period has passed with no requests being received. The default action for forking servers is to collect the status of any child processes that have exited, while in threading servers this method does nothing.
process_request(request, client_address)
Calls finish_request() to create an instance of the RequestHandlerClass. If desired, this function can create a new process or thread to handle the request; the ForkingMixIn and ThreadingMixIn classes do this.
server_activate()
Called by the server’s constructor to activate the server. The default behavior for a TCP server just invokes listen() on the server’s socket. May be overridden.
server_bind()
Called by the server’s constructor to bind the socket to the desired address. May be overridden.
verify_request(request, client_address)
Must return a Boolean value; if the value is True, the request will be processed, and if it’s False, the request will be denied. This function can be overridden to implement access controls for a server. The default implementation always returns True.
'''
五、socket 粘包
'''
socket 粘包
ftp server
1.读取文件名
2.检测文件是否存在
3.打开文件
4.检测文件大小
5.发送文件大小和md5给客户端
6.等客户端确认
7.开始边读变发数据
'''
import hashlib
m = hashlib.md5()
m.update(b"tset")
m.update(b"abc")
print(m.hexdigest)
m2 = hashlib.md5()
m2.update(b"tsetabc")
print(m2.hexdigest)