麦子学院 2017-07-06 11:01
Python的socket详解
回复:0 查看:2593
一. socket模块
socket
,俗称套接字,其实就是一个
ip
地址和端口的组合。类似于这样的形式
(ip, port),
其中
ip
代表的是某个主机,
port
代表的是某个应用,我们可以通过
socket
和另外的一台主机进行通信。
关于socket
源码的解析在
tarnado
系列文章中,正在写中。。。。。
1. 通信的方式
tcp
通信
udp
通信
基于unix
的通信
2. socket的方法
#
暂时知道的也就这么多,之后要是在用到其他的我会继续进行保存
Methods of
socket objects (keyword arguments
not allowed):
_accept() --
accept connection, returning new
socket fd
and client address
bind(addr) --
bind the
socket to a
local address
给本地地址绑定一个
socket
套接字
close() --
close the
socket
关闭一个套接字
connect(addr) --
connect the
socket to a remote address
连接到远端主机
connect_ex(addr) --
connect,
return an error code instead of an exception
dup() --
return a new
socket fd duplicated from fileno()
fileno() --
return underlying file descriptor
getpeername() --
return remote address
getsockname() --
return
local address
getsockopt(level, optname[, buflen]) -- get
socket options
gettimeout() --
return timeout
or None
listen([n]) -- start listening
for incoming connections
recv(buflen[, flags]) -- receive data
接受数据
recv_into(buffer[, nbytes[, flags]]) -- receive data (into a buffer)
接受数据到缓冲区中,
recvfrom(buflen[, flags]) -- receive data
and sender's address
recvfrom_into(buffer[, nbytes, [, flags])
-- receive data and sender'
s address (into a buffer)
sendall(data[, flags]) --
send all data
发送数据给远端主机,
3.x
之后只能发送字节形式,因此在发送的时候一般要进行转换
bytes
send(data[, flags]) --
send data, may
not
send all of it
也是发送数据,区别在于
send
发送的不完整,随机进行发送的,二sendall
发送的完整
sendto(data[, flags], addr) --
send data to a
given address
基于
udp
发送数据的
setblocking(0 | 1) -- set
or clear the blocking I/O flag
是否设置成阻塞模式
0
代表阻塞,
1
代表非阻塞
setsockopt(level, optname, value) -- set
socket options
设置一些
socket
的桉树
settimeout(None | float) -- set
or clear the timeout
设置超时市场
shutdown(how) -- shut down traffic in one
or both directions
if_nameindex() --
return all network interface indices
and names
if_nametoindex(name) --
return the corresponding interface
index
if_indextoname(
index) --
return the corresponding interface name
二. 简单的聊天机器人
如果发送一个数据,服务器就会给他回复一个数据 +
你好
1 # -*- coding:utf-8 -*-
2 # zhou
3 # 2017/7/3
4
5
import socket
6 #
创建一个
server
对象
7 server_obj = socket.socket()
8 #
绑定一下端口
9 server_obj.bind(("127.0.0.1", 8888, ))
10 #
设置监听的等待队列长度为
5,
当大于
5
的时候就拒绝连接
11 server_obj.listen(5)
12
13
while
True:
14 #
等待接受客户端的连接
,
为阻塞方式
15 conn, address = server_obj.accept()
16 #
发送欢迎信息
17 conn.sendall(bytes("
欢迎来到简单的聊天室
..", encoding='utf-8'))
18
while
True:
19 #
接受到对面的消息就会把对面消息后面加上你好重新发送回去
20 ret = str(conn.recv(1024), encoding='utf-8')
21
if ret == 'q':
22 #
如果对面发送的为
q
就退出
23
break
24 conn.sendall(bytes(ret + ",
你好
", encoding='utf-8'))
server
# -*- coding:utf-8 -*-# zhou# 2017/7/3
import
socket
client =
socket.
socket()
client.connect(("127.0.0.1", 8888, ))#
接受欢迎信息并打印
ret = str(client.recv(1024),
encoding='utf-8')
print(ret)
while True:
message = input("
请输入您要发送的内容
:")
client.sendall(bytes(message,
encoding='utf-8'))
if message == 'q':
break
ret = str(client.recv(1024),
encoding='utf-8')
print(ret)
client
三. 简单的ftp上传
实现了将一个图片上传到服务器端
1 # -*- coding:utf-8 -*-
2 # zhou
3 # 2017/7/2
4
5
import socket
6
7 server = socket.socket()
8 server.bind(("127.0.0.1", 9998, )) #
绑定
ip
9 server.listen(5)
10
11
while
True:
12 conn, address = server.accept()
13 #
连接之后首先接收文件大小
14 file_size = int(str(conn.recv(1024), encoding='utf-8'))
15 #
用来解决粘包问题的
16 conn.sendall(bytes("1001", encoding='utf-8'))
17 #
已经接受的文件大小
18 has_size = 0
19 num = 1
20 #
连接之后接收文件
21 f = open("new.jpg", 'wb')
22
while
True:
23 num += 1
24
if file_size == has_size:
25
break
26 data = conn.recv(1024)
27 f.write(data)
28 has_size += len(data)
29 f.close() #
关闭文件
ftpserver
1 # -*- coding:utf-8 -*-
2 # zhou
3 # 2017/7/2
4
5
6
import os
7
import socket
8
9 client = socket.socket()
10
11 client.connect(("127.0.0.1", 9998), )
12 #
传送文件大小
13 file_size = os.stat("1.jpg").st_size
14 print(file_size)
15 #
发送文件大小
16 client.sendall(bytes(str(file_size), encoding='utf-8'))
17 client.recv(1024) #
解决粘包问题
18 #
发送文件
19
with open("1.jpg", 'rb')
as f:
20
for line
in f:
21 client.sendall(line)
22 client.close()
ftpclient
四. 粘包问题的解决
对于上面第三个ftp
上传进行的描述,
解决粘包的问题,当我们上传一个文件的时候,首先上传他的大小,当我们上传完大小之后要在写一句接受的语句,而服务器端在接受到文件大小之后要给我们立马发送一个数据用来确认,这样我们就可以完美的将数据喝大小分割开了。
来源:
博客园