# socket是应用层与TCP/IP协议通讯的中间软件抽象层,它是一组接口。它把复杂的TCP/IP协议隐藏到socket #接口的后面,让socket去组织数据,以符合指定的协议。 # socket是一个模块,使用它来创建两个程序之间的链接和通讯。也能够把socket看作是ip+port,由于ip标识 #互联网中一台主机的位置,而port标识这台主机上的一个应用程序,只要确立ip和port就能够找到一个应用程序, #而且使用socket模块来与这个应用程序通讯。 # 先启动server,等待client发信息。 #网络传输的是bytes,recv接收以后,须要decode解码。 #encode编码,把str转化为bytes。 # 1、基于TCP的socket服务: # 一、server服务端: # 1.1 import socket sk = socket.socket() #买手机--建立套接字 # sk.setsockopt(socket.SOL_SOCKET,socket.SO_REUSEADDR,1)避免服务重启的时候报address already in use sk.bind(('127.0.0.1',8080)) #绑定手机卡--绑定端口:sk.bind(('ip','port')),bind(元祖) # 127.0.0.1是本机的回环地址,用于本机内部应用程序的通讯。 sk.listen() #监听,等待有人给我打电话--侦听客户请求 conn,addr = sk.accept() #接收到别人的电话,--接受客户端链接 # 获得了链接conn(connection),和别人的地址addr(address) #接收、发送--recv、send ret = conn.recv(1024) #听别人说话,--接收客户端信息 # 接收1024个字节,若是接收更长的信息能够填写2048或其余更大的数字,recv(receive)接收 print(ret.decode('utf-8')) conn.send(b'hi,client') #和别人说话,必须传一个bytes类型。--向客户端发送信息。b'hi,client'至关于'hi,client'.encode('utf-8')) ret = conn.recv(1024) print(ret.decode('utf-8'))#接收的是bytes,要解码为utf-8 conn.send(bytes('你也不错',encoding = 'utf-8')) #conn.send('你也不错'.encode('utf-8')) conn.close() #挂电话--关闭客户端套接字 sk.close() #关手机--关闭服务器套接字 # 1.2 不停跟client聊天,直到说bye才结束。 import socket sk = socket.socket() sk.bind(('127.0.0.1',8082)) sk.listen() conn,addr = sk.accept() while True: ret = conn.recv(1024).decode('utf-8') if ret == 'bye': print(ret) conn.send(b'bye') break print(ret) info = input('>>>') conn.send(bytes(info,encoding = 'utf-8'))#conn.send(info.encode('utf-8')) conn.close() sk.close() # 二、client客户端: # 2.1 import socket sk = socket.socket() #买手机 sk.connect(('127.0.0.1',8080))#拨号,链接别人的地址和端口 sk.send(b'hello,server') #和别人说话 ret = sk.recv(1024) #听别人说话 print(ret.decode('utf-8')) sk.send(bytes('你很好',encoding = 'utf-8')) ret = sk.recv(1024) print(ret.decode('utf-8')) sk.close() #关手机 # 2.2 不停跟server聊天,直到说bye才结束。 import socket sk = socket.socket() sk.connect(('127.0.0.1',8082)) while True: info = input('>>>') sk.send(bytes(info,encoding = 'utf-8')) ret = sk.recv(1024).decode('utf-8') print(ret) if ret == 'bye': sk.send(b'bye') break sk.close() # 2、基于UDP的socket服务:不须要链接。 # 1.1 server服务端: import socket sk = socket.socket(type=socket.SOCK_DGRAM) sk.bind(('127.0.0.1',9000)) #没有listen监听和accept接收链接 ret,addr = sk.recvfrom(1024) #接收client的addr是元祖,元祖没有decode属性,因此这里不能写sk.recvfrom(1024).decode('utf-8') print(ret.decode('utf-8')) sk.sendto(bytes('你好client',encoding='utf-8'),addr) #发送的时候须要填写client的addr地址 sk.close() # 1.2 client客户端: import socket sk = socket.socket(type=socket.SOCK_DGRAM) ip_port = ('127.0.0.1',9000) #server的地址和端口 sk.sendto(bytes('你好server',encoding='utf-8'),ip_port)#发送的时候须要把本身的地址一块儿发给server ret,addr = sk.recvfrom(1024) print(ret.decode('utf-8')) sk.close() # 2.1 一个服务器端 对 两个客户端:例如qq聊天 #服务器端: import socket sk = socket.socket(type=socket.SOCK_DGRAM) sk.bind(('127.0.0.1',9000)) while True: ret,addr = sk.recvfrom(1024) print(ret.decode('utf-8')) info = input('>>>') sk.sendto(bytes(info,encoding='utf-8'),addr) sk.close() #客户端1: import socket sk = socket.socket(type=socket.SOCK_DGRAM) ip_port = ('127.0.0.1',9000) while True: info = input('>>>') sk.sendto(bytes(('\033[31mclient1:%s\033[0m'%info).encode('utf-8')),ip_port) ret,addr = sk.recvfrom(1024) print(ret.decode('utf-8')) sk.close() #客户端2: import socket sk = socket.socket(type=socket.SOCK_DGRAM) ip_port = ('127.0.0.1',9000) while True: info = input('>>>') sk.sendto(bytes(('\033[31mclient2:%s\033[0m'%info).encode('utf-8')),ip_port) ret,addr = sk.recvfrom(1024) print(ret.decode('utf-8')) sk.close()