10.socket网络编程

套接字工做流程

先从服务器端提及。服务器端先初始化Socket,而后与端口绑定(bind),对端口进行监听(listen),调用accept阻塞,等待客户端链接。在这时若是有个客户端初始化一个Socket,而后链接服务器(connect),若是链接成功,这时客户端与服务器端的链接就创建了。客户端发送数据请求,服务器端接收请求并处理请求,而后把回应数据发送给客户端,客户端读取数据,最后关闭链接,一次交互结束。python

Socket Families(地址簇)

socket.AF_UNIX unix本机进程间通讯 服务器

socket.AF_INET IPV4 并发

socket.AF_INET6  IPV6ssh

Socket Types

socket.SOCK_STREAM  #for tcpsocket

socket.SOCK_DGRAM   #for udptcp

Socket 参数

s.bind(address)     绑定(host,port)ide

s.listen(backlog)   开始监听传入链接。backlog指定在拒绝链接以前,能够挂起的最大链接数量post

s.accept()             接受链接并返回(conn,address),其中conn是新的套接字对象,能够用来接收和发送数据。address是链接客户端的地址。spa

s.connect(address)      address的格式为元组(hostname,port)unix

s.setblocking(bool)    是否阻塞(默认True),若是设置False,那么accept和recv时一旦无数据,则报错。

s.close()                  关闭套接字

s.recv(bufsize)        bufsize指定最多能够接收的数量

s.send(string)          将string中的数据发送到链接的套接字。返回值是要发送的字节数量,该数量可能小于string的字节大小。即:可能未将指定内容所有发送。

s.sendall(string)       将string中的数据发送到链接的套接字,但在返回以前会尝试发送全部数据。成功返回None,失败则抛出异常。

                                 内部经过递归调用send,将全部内容发送出去。

s.settimeout(timeout)  设置套接字操做的超时期,timeout是一个浮点数,单位是秒。值为None表示没有超时期。通常,超时期应该在

                                    刚建立套接字时设置,由于它们可能用于链接的操做(如 client 链接最多等待5s )

s.getpeername()         返回链接套接字的远程地址。返回值一般是元组(ipaddr,port)

 

服务端

  1. 建立socket对象
  2. 绑定IP和端口 绑定 bind()
  3. 开始监听连接 监听 listen()
  4. 阻塞 , 等待客户端成功链接 阻塞 accept()
  5. 接收请求数据 接收 recv()
  6. 处理并发送请求数据 发送 send()
  7. 关闭 close()

客户端

  1. 建立socket对象
  2. 链接服务端 , 按照IP和端口链接 链接 connet()
  3. 发送请求数据 发送 send()
  4. 接收请求数据 接收 recv()
  5. 关闭 close()

简单socket

 server.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)   重用ip和端口 ,但其它client只是挂起状态。只有一个能交互

import socket
# 建立socket对象
sock = socket.socket()
# 绑定IP和端口,参数是一个元组(ip,port)
sock.bind(('localhost', 8080))
# 开始监听,最大挂起5个
sock.listen(5)
# 阻塞,等待链接
conn,addr = sock.accept()
# 接收请求数据,接收大小为1024字节
content = conn.recv(1024)
print(content.decode())
# 发送请求结果,必须以bytes类型
conn.send(b'jieshouwanbi')
# 关闭连接
conn.close()
s.server
import socket
# 建立socket对象
sock = socket.socket()
# 创建连接
sock.connect(('localhost', 8080))
# 发送请求数据,必须以bytes类型
sock.send(b"hello")
# 接收请求结果
content = sock.recv(1024)
print(content.decode())
# 关闭套接字
sock.close()
s.client

SSH

 1 import socket ,os
 2 server = socket.socket()   #建立socket对象
 3 server.bind(('localhost',9999) )  #绑定ip和port
 4 server.listen()          #开始监听
 5
 6 while True:
 7     conn, addr = server.accept()   #阻塞 等待链接
 8     print("new conn:",addr)
 9     while True:
10         print("等待新指令")
11         data = conn.recv(1024)      #接收客户端发过来的命令
12         if not data:
13             break
14         print("执行指令:",data)
15         cmd_res = os.popen(data.decode()).read() #执行客户端发过来的命令,返回信息长度(接收字符串,执行结果也是字符串)
16         print("before send",len(cmd_res))      #信息的长度
17         if len(cmd_res) ==0:
18             cmd_res = "cmd has no output..."
19
20         conn.send( str(len(cmd_res.encode())).encode("utf-8")    )   #先发命令执行的结果信息大小给客户端
21         client_ack = conn.recv(1024)       #防止粘包,客户端ack
22         conn.send(cmd_res.encode("utf-8"))    #发送信息
23         print("send done")
24
25 server.close()
server_ssh
 1 import socket
 2 client = socket.socket()
 3 client.connect(('localhost',9999))
 4
 5 while True:
 6     cmd = input(">>:").strip()         #输入命令
 7     if len(cmd) == 0: continue
 8     client.send(cmd.encode("utf-8"))   #发送命令给server端
 9     cmd_res_size = client.recv(1024)   #接受server端发过来的命令结果信息长度
10     print("命令结果大小:",cmd_res_size)
11     client.send("准备接受".encode('utf-8'))   #防止粘包
12     received_size = 0    #已经接受数据的大小
13     received_data = b''
14     while received_size < int(cmd_res_size.decode()):
15         data = client.recv(1024)   #只要小于,就一直接收
16         received_size += len(data) #每次收到的有可能小于1024,因此
17                                                  必须用len判断
18         #print(data.decode())
19         received_data += data
20     else:
21         print("cmd res receive done...",received_size)
22         print(received_data.decode())
23
24
25 client.close()
client

ftp传文件

?
1
2
3
4
5
6
7
8
9
ftp server
     1. 读取文件名
     2. 检测文件是否存在
     3. 打开文件
     4. 检测文件大小
     5. 发送文件大小给客户端
     6. 等客户端确认
     7. 开始边读边发数据
     8. 发送md5 
 1 import socket ,os
 2 server = socket.socket()
 3 server.bind(('localhost',9999))
 4 server.listen()
 5
 6 while True:
 7     conn, addr = server.accept()
 8     print("new conn:",addr)
 9     while True:
10         print("等待新指令")
11         data = conn.recv(1024)
12         if not data:
13             print("客户端已断开")
14             break
15         cmd,filename = data.decode().split()
16         print(filename)
17         if os.path.isfile(filename):   #判断是不是文件
18            f = open(filename,"rb")     #打开文件
19            file_size = os.stat(filename).st_size      #文件大小
20            conn.send( str(file_size).encode() )       #send file size  防止粘包
21            conn.recv(1024)                            #wait for ack
22            for line in f:
23               conn.send(line)                         #开始发送
24            f.close()
25         print("send done")
26
27 server.close()
ftp_server
 1 import socket
 2 import hashlib
 3 client = socket.socket()
 4 client.connect(('localhost', 9999))
 5
 6 while True:
 7     cmd = input(">>:").strip()
 8     if len(cmd) == 0: continue
 9
10     if cmd.startswith("get"):                   #判断是否以字符串‘get’ 开头
11         client.send(cmd.encode())               #把须要下载的文件发给server端
12         server_response = client.recv(1024)     #接收server端发过来的文件大小
13         print("servr response:", server_response)     #打印文件大小
14         client.send(b"ready to recv file")            #防止粘包
15         file_total_size = int(server_response.decode())
16         received_size = 0                  #已经接收的大小
17         filename = cmd.split()[1]
18         f = open(filename + ".new", "wb")      #建立新文件  用于保存
19
20         while received_size < file_total_size:
21             if file_total_size - received_size > 1024:  # 要收不止一次
22                 size = 1024
23             else:  # 最后一次了,剩多少收多少
24                 size = file_total_size - received_size
25                 print("last receive:", size)
26
27             data = client.recv(size)
28             received_size += len(data)
29             f.write(data)
30             # print(file_total_size,received_size)
31         else:
32             print("file recv done", received_size, file_total_size)
33             f.close()
34 client.close()
ftp_client
 1 import hashlib
 2 import socket ,os,time
 3 server = socket.socket()
 4 server.bind(('localhost',9999))
 5 server.listen()
 6 while True:
 7     conn, addr = server.accept()
 8     print("new conn:",addr)
 9     while True:
10         print("等待新指令")
11         data = conn.recv(1024)
12         if not data:
13             print("客户端已断开")
14             break
15         cmd,filename = data.decode().split()
16         print(filename)
17         if os.path.isfile(filename):
18            f = open(filename,"rb")
19            m = hashlib.md5()
20            file_size = os.stat(filename).st_size
21            conn.send( str(file_size).encode() ) #send file size
22            conn.recv(1024) #wait for ack
23            for line in f:
24               m.update(line)
25               conn.send(line)
26            print("file md5", m.hexdigest())
27            f.close()
28            conn.send(m.hexdigest().encode()) #send md5
29         print("send done")
30
31 server.close()
md5_ftp_server
 1 import socket
 2 import hashlib
 3 client = socket.socket()
 4 client.connect(('localhost', 9999))
 5
 6 while True:
 7     cmd = input(">>:").strip()
 8     if len(cmd) == 0: continue
 9     if cmd.startswith("get"):
10         client.send(cmd.encode())
11         server_response = client.recv(1024)
12         print("servr response:", server_response)
13         client.send(b"ready to recv file")
14         file_total_size = int(server_response.decode())
15         received_size = 0
16         filename = cmd.split()[1]
17         f = open(filename + ".new", "wb")
18         m = hashlib.md5()
19
20         while received_size < file_total_size:
21             if file_total_size - received_size > 1024:  # 要收不止一次
22                 size = 1024
23             else:  # 最后一次了,剩多少收多少
24                 size = file_total_size - received_size
25                 print("last receive:", size)
26
27             data = client.recv(size)
28             received_size += len(data)
29             m.update(data)
30             f.write(data)
31             print(file_total_size,received_size)
32         else:
33             new_file_md5 = m.hexdigest()
34             print("file recv done", received_size, file_total_size)
35             f.close()
36         server_file_md5 = client.recv(1024)
37         print("server file md5:", server_file_md5)
38         print("client file md5:", new_file_md5)
39
40 client.close()
md5_ftp_cli
相关文章
相关标签/搜索