标签:image lan -- 工作组 端口号 组成 base 第二部分 sel
传输层-->四层交换机, 四层的路由器 网络层-->路由器, 三层交换机 数据链路层-->网桥, 以太网交换机, 网卡 物理层-->中继器, 集线器, 双绞线
传输层-->tcp与udp协议 网络层-->ip协议 数据链路层-->arp协议
import socket def tcp_srv(): # 1. 建立socket负责具体通信,这个socket其实只负责接受对方的请求,真正通信的是链接后从新建立的socket # 需要用到两个参数 # AF_INET: 含义同udp一致 # SOCK_STREAM: 表明是使用的tcp进行通信 sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) # 2. 绑定端口和地址 # 此地址信息是一个元祖类型内容,元祖分两部分,第一部分为字符串,代表ip,第二部分为端口,是一个整数,推荐大于10000 addr = ("127.0.0.1", 8998) sock.bind(addr) # 3. 监听接入的访问socket sock.listen() # 4. 接受访问的socket,可以理解接受访问即建立了一个通讯的链接通路 # accept返回的元祖第一个元素赋值给skt,第二个赋值给addr skt,addr = sock.accept() # 5. 接受对方的发送内容,利用接收到的socket接收内容 # 500代表接收使用的buffersize #msg = skt.receive(500) msg = skt.recv(500) # 接受到的是bytes格式内容 # 想得到str格式的,需要进行解码 msg = msg.decode() rst = "Received msg: {0} from {1}".format(msg, addr) print(rst) # 6. 如果有必要,给对方发送反馈信息 skt.send(rst.encode()) # 7. 关闭链接通路 skt.close() if __name__ == "__main__": print("Starting tcp server.......") tcp_srv() print("Ending tcp server.......")
import socket def tcp_clt(): # 1. 建立通信socket sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) # 2. 链接对方,请求跟对方建立通路 addr = ("127.0.0.1", 8998) sock.connect(addr) # 3. 发送内容到对方服务器 msg = "Hello World!" sock.send(msg.encode()) # 4. 接受对方的反馈 rst = sock.recv(500) print(rst.decode()) # 5. 关闭链接通路 sock.close() if __name__ == "__main__": tcp_clt()
import socket # 模拟服务器的函数 def serverFunc(): # 1. 建立socket # socket.AF_INET: 使用ipv4协议族 # socket.SOCK_DGRAM: 使用UDP通信 sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) # 2. 绑定ip和port # 127.0.0.1: 这个ip地址代表的本机 # 7852: 随便指定的端口号 # 地址是一个tuple类型, (ip, port) addr = ("127.0.0.1", 7852) sock.bind(addr) # 3. 接受对方的消息 # 等待方式为死等 # recvfrom接受返回值是一个元组, 前一项表示数据, 后一项表示地址 # 参数的含义是缓冲区大小 # rst = server_sock.recvfrom(500)等效于下面 data, addr = sock.recvfrom(500) print("服务器接受的数据: ", data) print(type(data)) # 发送过来的数据是bytes格式, 必须通过解码才能得到str格式内容 # decode默认参数是UTF-8 text = data.decode("utf-8") print(text) print(type(text)) # 4. 给客户端返回消息 rsp = "我不饿!" # 发送的数据需要编码成bytes格式 # 默认编码是utf-8 data = rsp.encode("utf-8") sock.sendto(data, addr) if __name__ == ‘__main__‘: print("Starting server..........") serverFunc() print("Ending server.............")
import socket # 模拟客户端 def clientFunc(): # 1. 创建一个client sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) # 2. 发送内容到指定服务器 text = "Hello World" # 发送数据必须是bytes格式 data = text.encode("utf-8") # 发送 sock.sendto(data, ("127.0.0.1", 7852)) data, addr = sock.recvfrom(500) text = data.decode("utf-8") print(text) if __name__ == ‘__main__‘: clientFunc()
family: 地址系列应为AF_INET(默认值),AF_INET6,AF_UNIX,AF_CAN或AF_RDS。(AF_UNIX 域实际上是使用本地 socket 文件来通信)
type: 套接字类型应为SOCK_STREAM(默认值),SOCK_DGRAM,SOCK_RAW或其他SOCK_常量之一。
SOCK_STREAM 是基于TCP的,有保障的(即能保证数据正确传送到对方)面向连接的SOCKET,多用于资料传送。
SOCK_DGRAM 是基于UDP的,无保障的面向消息的socket,多用于在网络上发广播信息。
proto:协议号通常为零,可以省略,或者在地址族为AF_CAN的情况下,协议应为CAN_RAW或CAN_BCM之一。
fileno: 如果指定了fileno,则其他参数将被忽略,导致带有指定文件描述符的套接字返回。
与socket.fromfd()不同,fileno将返回相同的套接字,而不是重复的。
这可能有助于使用socket.close()关闭一个独立的插座。
服务端套接字函数
s.bind() 绑定(主机,端口号)到套接字
s.listen() 开始TCP监听
s.accept() 被动接受TCP客户的连接,(阻塞式)等待连接的到来
客户端套接字函数
s.connect() 主动初始化TCP服务器连接
s.connect_ex() connect()函数的扩展版本,出错时返回出错码,而不是抛出异常
公共用途的套接字函数
s.recv() 接收TCP数据
s.send() 发送TCP数据
s.sendall() 发送TCP数据
s.recvfrom() 接收UDP数据
s.sendto() 发送UDP数据
s.getpeername() 连接到当前套接字的远端的地址
s.getsockname() 当前套接字的地址
s.getsockopt() 返回指定套接字的参数
s.setsockopt() 设置指定套接字的参数
s.close() 关闭套接字
面向锁的套接字方法
s.setblocking() 设置套接字的阻塞与非阻塞模式
s.settimeout() 设置阻塞套接字操作的超时时间
s.gettimeout() 得到阻塞套接字操作的超时时间
面向文件的套接字的函数
s.fileno() 套接字的文件描述符
s.makefile() 创建一个与该套接字相关的文件
官方文档对socket模块下的socket.send()和socket.sendall()解释如下: socket.send(string[, flags]) Send data to the socket. The socket must be connected to a remote socket. The optional flags argument has the same meaning as for recv() above. Returns the number of bytes sent. Applications are responsible for checking that all data has been sent; if only some of the data was transmitted, the application needs to attempt delivery of the remaining data. send()的返回值是发送的字节数量,这个数量值可能小于要发送的string的字节数,也就是说可能无法发送string中所有的数据。如果有错误则会抛出异常。 – socket.sendall(string[, flags]) Send data to the socket. The socket must be connected to a remote socket. The optional flags argument has the same meaning as for recv() above. Unlike send(), this method continues to send data from string until either all data has been sent or an error occurs. None is returned on success. On error, an exception is raised, and there is no way to determine how much data, if any, was successfully sent. 尝试发送string的所有数据,成功则返回None,失败则抛出异常。 故,下面两段代码是等价的: #sock.sendall(‘Hello world\n‘) #buffer = ‘Hello world\n‘ #while buffer: # bytes = sock.send(buffer) # buffer = buffer[bytes:]
import socketserver class Myserver(socketserver.BaseRequestHandler): def handle(self): self.data = self.request.recv(1024).strip() print("{} wrote:".format(self.client_address[0])) print(self.data) self.request.sendall(self.data.upper()) if __name__ == "__main__": HOST, PORT = "127.0.0.1", 9999 # 设置allow_reuse_address允许服务器重用地址 socketserver.TCPServer.allow_reuse_address = True # 创建一个server, 将服务地址绑定到127.0.0.1:9999 server = socketserver.TCPServer((HOST, PORT),Myserver) # 让server永远运行下去,除非强制停止程序 server.serve_forever()
import socket HOST, PORT = "127.0.0.1", 9999 data = "hello" # 创建一个socket链接,SOCK_STREAM代表使用TCP协议 with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as sock: sock.connect((HOST, PORT)) # 链接到客户端 sock.sendall(bytes(data + "\n", "utf-8")) # 向服务端发送数据 received = str(sock.recv(1024), "utf-8")# 从服务端接收数据 print("Sent: {}".format(data)) print("Received: {}".format(received))
标签:image lan -- 工作组 端口号 组成 base 第二部分 sel
原文地址:https://www.cnblogs.com/lijianqing/p/10288917.html