socket通常也称作套接字,用于描述ip地址和端口,是一个通信链的句柄,应用程序通常通过套接字向网络发出请求或者应答网络请求。
socket起源于unix,而unix/linux基本哲学之一就是“一切皆文件”,对于文件用【打开】【读写】【关闭】模式来操作。socket就是该模式的一个实现,socket即是一种特殊的文件,一些socket函数就是对其进行的操作(读/写io、打开、关闭)
socket和file的区别:
file模块是针对某个指定文件进行【打开】【读写】【关闭】
一. 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
[*] not available on all platforms!
二. 简单的聊天机器人如果发送一个数据,服务器就会给他回复一个数据 + 你好
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 break24 conn.sendall(bytes(ret + ,你好, encoding='utf-8'))
server
# -*- coding:utf-8 -*-# zhou# 2017/7/3import 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':breakret = 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 = 019 num = 120 # 连接之后接收文件21 f = open(new.jpg, 'wb')22 while true:23 num += 124 if file_size == has_size:25 break26 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_size14 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上传进行的描述,
解决粘包的问题,当我们上传一个文件的时候,首先上传他的大小,当我们上传完大小之后要在写一句接受的语句,而服务器端在接受到文件大小之后要给我们立马发送一个数据用来确认,这样我们就可以完美的将数据喝大小分割开了。
以上就是python中对socket的详细介绍的详细内容。