python repl communication_Python网络编程——Socket基础(一)

A network socket is an endpoint of a connection across a computer network. Today, most communication between computers is based on the Internet Protocol; therefore most network sockets are Internet sockets. More precisely, a socket is a handle (abstract reference) that a local program can pass to the networking application programming interface (API) to use the connection, for example "send this data on this socket". Sockets are internally often simply integers, which identify which connection to use.

网络套接字是跨越计算机网络的连接的端点。 今天,计算机之间的大部分通信都基于互联网协议; 因此大多数网络套接字都是Internet套接字。 更确切地说,套接字是本地程序可以传递给网络应用程序编程接口(API)以使用连接的句柄(抽象引用),例如“在此套接字上发送此数据”。 套接字在内部通常只是整数,用于标识要使用的连接。

For example, to send "Hello, world!" via TCP to port 80 of the host with address 1.2.3.4, one might get a socket, connect it to the remote host, send the string, then close the socket:

A socket API is an application programming interface (API), usually provided by the operating system, that allows application programs to control and use network sockets. Internet socket APIs are usually based on the Berkeley sockets standard. In the Berkeley sockets standard, sockets are a form of file descriptor (a file handle), due to the Unix philosophy that "everything is a file", and the analogies between sockets and files: you can read, write, open, and close both. In practice the differences mean the analogy is strained, and one instead use different interfaces (send and receive) on a socket. In inter-process communication, each end will generally have its own socket, but these may use different APIs: they are abstracted by the network protocol.

套接字API是应用程序编程接口(API),通常由操作系统提供,允许应用程序控制和使用网络套接字。 Internet套接字API通常基于Berkeley套接字标准。 在伯克利套接字标准中,套接字是一种文件描述符(文件句柄)的形式,由于Unix的哲学是“一切都是文件”,以及套接字和文件之间的类比:你可以读,写,打开和关闭 都。 在实践中,差异意味着类比紧张,而在插座上使用不同的接口(发送和接收)。 在进程间通信中,每一端通常都有自己的套接字,但这些套接字可能使用不同的API:它们被网络协议抽象出来。

A socket address is the combination of an IP address and a port number, much like one end of a telephone connection is the combination of a phone number and a particular extension. Sockets need not have an address (for example for only sending data), but if a program binds a socket to an address, the socket can be used to receive data sent to that address. Based on this address, internet sockets deliver incoming data packets to the appropriate application process or thread.

套接字地址是IP地址和端口号的组合,就像电话连接的一端是电话号码和特定分机的组合。 套接字不必具有地址(例如仅用于发送数据),但是如果程序将套接字绑定到地址,套接字可用于接收发送到该地址的数据。 基于这个地址,互联网套接字将传入的数据包传递给适当的应用程序进程或线程。

socket()

Socket Families(地址簇)

socket.AF_UNIX unix 本机进程间通信

socket.AF_INET IPV4 默认为IPV4

socket.AF_INET6  IPV6

These constants represent the address (and protocol) families, used for the first argument to socket(). If the AF_UNIX constant is not defined then this protocol is unsupported. More constants may be available depending on the system.

这些常量表示地址(和协议)族,用于socket()的第一个参数。 如果未定义AF_UNIX常量,则此协议不受支持。 取决于系统,可能有更多的常量。

Socket Types(套接字类型)

socket.SOCK_STREAM  #for tcp

socket.SOCK_DGRAM   #for udp

socket.SOCK_RAW     #原始套接字,普通的套接字无法处理ICMP、IGMP等网络报文,而SOCK_RAW可以;其次,SOCK_RAW也可以处理特殊的IPv4报文;此外,利用原始套接字,可以通过IP_HDRINCL套接字选项由用户构造IP头。

socket.SOCK_RDM  #是一种可靠的UDP形式,即保证交付数据报但不保证顺序。SOCK_RAM用来提供对原始协议的低级访问,在需要执行某些特殊操作时使用,如发送ICMP报文。SOCK_RAM通常仅限于高级用户或管理员运行的程序使用。

socket.SOCK_SEQPACKET #废弃了

These constants represent the socket types, used for the second argument to socket(). More constants may be available depending on the system. (Only SOCK_STREAM and SOCK_DGRAM appear to be generally useful.)

Socket 方法

socket.socket(family=AF_INET, type=SOCK_STREAM, proto=0, fileno=None)

Create a new socket using the given address family, socket type and protocol number. The address family should be AF_INET (the default), AF_INET6, AF_UNIX, AF_CAN or AF_RDS. The socket type should beSOCK_STREAM (the default), SOCK_DGRAM, SOCK_RAW or perhaps one of the other SOCK_ constants. The protocol number is usually zero and may be omitted or in the case where the address family is AF_CAN the protocol should be one of CAN_RAW or CAN_BCM. If fileno is specified, the other arguments are ignored, causing the socket with the specified file descriptor to return. Unlike socket.fromfd(), fileno will return the same socket and not a duplicate. This may help close a detached socket using socket.close().

使用给定的地址系列,套接字类型和协议号创建一个新套接字。 地址系列应该是AF_INET(默认),AF_INET6,AF_UNIX,AF_CAN或AF_RDS。 套接字类型应该是SOCK_STREAM(默认),SOCK_DGRAM,SOCK_RAW或者其他SOCK_常量之一。 协议编号通常为零,可以省略,或者在地址族为AF_CAN的情况下,协议应该是CAN_RAW或CAN_BCM之一。 如果指定了fileno,则其他参数将被忽略,从而导致带有指定文件描述符的套接字返回。 与socket.fromfd()不同,fileno将返回相同的套接字,而不是重复的。 这可能有助于使用socket.close()关闭分离的套接字。

socket.socketpair([family[, type[, proto]]])

Build a pair of connected socket objects using the given address family, socket type, and protocol number. Address family, socket type, and protocol number are as for the socket() function above. The default family is AF_UNIX if defined on the platform; otherwise, the default is AF_INET.

使用给定的地址系列,套接字类型和协议编号构建一对连接的套接字对象。 地址族,套接字类型和协议号与上面的socket()函数一样。 如果在平台上定义,则默认系列是AF_UNIX; 否则,默认是AF_INET。

socket.create_connection(address[, timeout[, source_address]])

Connect to a TCP service listening on the Internet address (a 2-tuple (host, port)), and return the socket object. This is a higher-level function than socket.connect(): if host is a non-numeric hostname, it will try to resolve it for both AF_INET and AF_INET6, and then try to connect to all possible addresses in turn until a connection succeeds. This makes it easy to write clients that are compatible to both IPv4 and IPv6.

Passing the optional timeout parameter will set the timeout on the socket instance before attempting to connect. If no timeout is supplied, the global default timeout setting returned by getdefaulttimeout() is used.

If supplied, source_address must be a 2-tuple (host, port) for the socket to bind to as its source address before connecting. If host or port are ‘’ or 0 respectively the OS default behavior will be used.

连接到监听Internet地址的TCP服务(2元组(主机,端口)),然后返回套接字对象。 这是比socket.connect()更高级别的函数:如果主机是非数字主机名,它将尝试为AF_INET和AF_INET6解析它,然后尝试依次连接到所有可能的地址,直到连接成功。 这使得编写兼容IPv4和IPv6的客户端变得容易。

尝试连接之前,传递可选的timeout参数将在套接字实例上设置超时。 如果未提供超时,则使用由getdefaulttimeout()返回的全局默认超时设置。

如果提供,则在连接之前,source_address必须是套接字绑定到的源地址的2元组(主机,端口)。 如果主机或端口分别为“0”或0,则将使用操作系统默认行为。

socket.getaddrinfo(host, port, family=0, type=0, proto=0, flags=0)

#获取要连接的对端主机地址

sk.bind(address)

s.bind(address) 将套接字绑定到地址。address地址的格式取决于地址族。在AF_INET下,以元组(host,port)的形式表示地址。

sk.listen(backlog)

开始监听传入连接。backlog指定在拒绝连接之前,可以挂起的最大连接数量。

backlog等于5,表示内核已经接到了连接请求,但服务器还没有调用accept进行处理的连接个数最大为5,这个值不能无限大,因为要在内核中维护连接队列

sk.setblocking(bool)

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

sk.accept()

接受连接并返回(conn,address),其中conn是新的套接字对象,可以用来接收和发送数据。address是连接客户端的地址。

接收TCP 客户的连接(阻塞式)等待连接的到来

sk.connect(address)

连接到address处的套接字。一般,address的格式为元组(hostname,port),如果连接出错,返回socket.error错误。

sk.connect_ex(address)

同上,只不过会有返回值,连接成功时返回 0 ,连接失败时候返回编码,例如:10061

sk.close()

关闭套接字

sk.recv(bufsize[,flag])

接受套接字的数据。数据以字符串形式返回,bufsize指定最多可以接收的数量。flag提供有关消息的其他信息,通常可以忽略。

sk.recvfrom(bufsize[.flag])

与recv()类似,但返回值是(data,address)。其中data是包含接收数据的字符串,address是发送数据的套接字地址。

sk.send(string[,flag])

将string中的数据发送到连接的套接字。返回值是要发送的字节数量,该数量可能小于string的字节大小。即:可能未将指定内容全部发送。

sk.sendall(string[,flag])

将string中的数据发送到连接的套接字,但在返回之前会尝试发送所有数据。成功返回None,失败则抛出异常。

内部通过递归调用send,将所有内容发送出去。

sk.sendto(string[,flag],address)

将数据发送到套接字,address是形式为(ipaddr,port)的元组,指定远程地址。返回值是发送的字节数。该函数主要用于UDP协议。

sk.settimeout(timeout)

设置套接字操作的超时期,timeout是一个浮点数,单位是秒。值为None表示没有超时期。一般,超时期应该在刚创建套接字时设置,因为它们可能用于连接的操作(如 client 连接最多等待5s )

sk.getpeername()

返回连接套接字的远程地址。返回值通常是元组(ipaddr,port)。

sk.getsockname()

返回套接字自己的地址。通常是一个元组(ipaddr,port)

sk.fileno()

套接字的文件描述符

socket.sendfile(file, offset=0, count=None)

发送文件 ,但目前多数情况下并无什么卵用。

例子1:基础实现,只能一对一收发

server端

8f900a89c6347c561fdf2122f13be562.png

961ddebeb323a10fe0623af514929fc1.png

1 importsocket2

3 sever = socket.socket() #声明socket类型,生成socket连接对象

4 sever.bind(("localhost",4545)) #绑定socket服务的地址和端口

5 sever.listen() #监听

6 print("我要开始等电话了")7

8 whileTrue:9 conn,sddr = sever.accept() #等待电话,返回链接的标记位和链接地址

10 #conn是服务端生成的客户端链接实例

11 print("电话来了")12 whileTrue:13 data = conn.recv(1024) #通过标记来接受

14 if notdata:15 break

16 print("recv:",data.decode())17 conn.send(data.upper()) #通过标记来发送

18

19 sever.close()

View Code

client端

8f900a89c6347c561fdf2122f13be562.png

961ddebeb323a10fe0623af514929fc1.png

1 importsocket2

3 client = socket.socket() #声明socket类型,生成socket连接对象

4

5 client.connect(("localhost",4545)) #设置socket的地址和端口

6 whileTrue:7 mas = input(">>").strip()8 client.send(mas.encode("utf-8")) #发送的内容

9

10 data = client.recv(1024) #接受的内容

11 print(data.decode())12

13 client.close() #关闭socket

View Code

例子2:基本ssh

server端

8f900a89c6347c561fdf2122f13be562.png

961ddebeb323a10fe0623af514929fc1.png

1 importsocket,os2

3 server =socket.socket()4 server.bind(("localhost",4000))5 server.listen()6

7 whileTrue:8 conn,addr =server.accept()9 print("链接客户机",addr)10 whileTrue:11 data = conn.recv(1024)12 if notdata:13 print("客户机断开...")14 break

15 print("接收指令:",data)16 msg =os.popen(data.decode()).read()17 if len(msg) ==0:18 msg = "Have no message"

19 conn.send(str(len(msg.encode())).encode("utf-8"))20 data = conn.recv(1024) #防止粘包,进行交互

21 print(addr,data.decode())22 conn.send(msg.encode("utf-8"))23 print("信息发送成功")24

25 server.close()

View Code

client端

8f900a89c6347c561fdf2122f13be562.png

961ddebeb323a10fe0623af514929fc1.png

1 importsocket2

3 client =socket.socket()4 client.connect(("localhost",4000))5

6 whileTrue:7 cmd = input(">>:").strip()8 if len(cmd) ==0:9 continue

10 client.send(cmd.encode("utf-8"))11 msg_size = client.recv(1024)12 client.send("准备好接受数据了".encode("utf-8"))13 print(int(msg_size))14 msg_recv_size =015 msg = b""

16 while msg_recv_size

21 msg +=data22 else:23 print(msg_recv_size)24 print(msg.decode("utf-8"))25

26 client.close()

View Code

例子3:基本ftp

server端

8f900a89c6347c561fdf2122f13be562.png

961ddebeb323a10fe0623af514929fc1.png

1 importsocket,os2

3 server =socket.socket()4 server.bind(("0.0.0.0",9999))5 server.listen()6

7 whileTrue:8 conn,addr =server.accept()9 print("链接客户机",addr)10 whileTrue:11 print("等待新指令")12 data = conn.recv(1024)13 if notdata:14 print("客户机已断开")15 break

16

17 cmd,filename =data.decode().split()18 print("file name:",filename)19 ifos.path.isfile(filename):20 f = open(filename,"rb")21 file_size =os.stat(filename).st_size22 conn.send(str(file_size).encode("utf-8"))23 conn.recv(1024)24 for line inf:25 conn.send(line)26 f.close()27 print("send done")28

29 else:30 print("err :don't have this file")31

32 server.close()

View Code

client端

8f900a89c6347c561fdf2122f13be562.png

961ddebeb323a10fe0623af514929fc1.png

1 importsocket2

3 client =socket.socket()4 client.connect(("localhost",9999))5

6 whileTrue:7 cmd = input(">>:").strip()8 if len(cmd)==0:continue

9 if cmd.startswith("get"):10 client.send(cmd.encode("utf-8"))11 server_fsize = client.recv(1024)12 print("file size:",server_fsize.decode())13 client.send(b"ready to recv file")14 file_totle_size =int(server_fsize)15 receive_size =016 filename = cmd.split()[1]17 f = open(filename+"副本","wb")18 while receive_size<19 data="client.recv(1024)20" receive_size f.write print else:24 done f.close>

27 client.close()

View Code

19>
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值