本博客为菜作者在自学过程中的总结,希望能够帮助到大家。
socket模块常用函数
语法+案例
这里实例化的对象是sever
socket.socket() 创建一个对象
sever=socket.socket()
.bind(('服务端的ip',端口号))
绑定对象
sever.bind('127.0.0.1',9001)
.listen(数) 支持排队等待的个数
服务端一次连接一个人,其他的需要排队,最大能排几个人
sever.listen(5)
.accept() 等待客户端连接(程序会暂停)
conn,addr=sever.accept()
变量名=变量名1.recv(1024)
等待客户端发送消息(程序暂停)
date=conn.recv(1024) 接收的数据量为1024
数据的输出(网络传输的是字节,需要转为字符串)
print(date.decode('utf-8'))
消息回复
变量名1.sendall('内容'.encode('utf-8'))
发送消息并且编码为字节
变量名1.close() 关闭与此人的连接
变量名.close() 关闭服务端
变量名=socket.socket()
实例化对象
client=socket.socket()
变量名.connect(('服务端ip',端口号))
连接服务端(暂时也会暂停程序,连接上了才会执行下面程序)
client.connect('198.127.478',8001)
变量名.sendall('内容')
发送消息
client.sendall('i am so cool'.encode('utf-8'))
变量名=client.recv(1024)
等待消息回复(程序暂停)
reply=client.recv(1024)
变量名.close()
关闭连接(客户端关闭连接时会发送空白字符)
client.close()
1. socket()参数
family:
socket.AF_INET - IPv4(默认)
socket.AF_INET6 - IPv6
socket.AF_UNIX - 只能够用于单一的Unix系统进程间通信type:
socket.SOCK_STREAM - 流式socket, for TCP (默认)
socket.SOCK_DGRAM - 数据报式socket, for UDP
socket.SOCK_RAW - 原始套接字
socket.SOCK_RDM - 可靠UDP形式
socket.SOCK_SEQPACKET - 可靠的连续数据包服务
2. socket对象内建方法
服务端套接字方法:
s.bind()
- 绑定地址(host,port)到套接字,在AF_INET下,以元组(host,port)的形式表示地址。
s.listen()- 开启TCP监听,操作系统可以挂起的最大连接数量,该值至少为1。
s.accept()- 被动接受TCP客户端连接,(阻塞式)等待连接的到来。
客户端套接字方法:
s.connect()
- 主动初始化TCP服务器连接,一般address的格式为元组(hostname,port),如果连接出错,返回socket.error错误。
s.connect_ex()- connect()函数的扩展版本,出错时返回出错码,而不是抛出异常。
公共套接字方法:
s.recv()
- 接收TCP数据,数据以byte类型返回,bufsize指定要接收的最大数据量。
s.send()- 发送TCP数据,将string中的数据转化为byte类型发送到连接的套接字,返回值是要发送的字节数量,该数量可能小于string的字节大小。
s.sendall()- 发送完整TCP数据,将string中的数据转化为byte类型发送到连接的套接字,但在返回之前会尝试发送所有数据,成功返回None,失败则抛出异常。
s.recvfrom()- 接收UDP数据,与recv()类似,但返回值是(data,address),其中data是包含接收数据的字符串,address是客户端的套接字地址。
s.sendto()- 发送UDP数据,将数据发送到套接字,参数形式为(data,(address,port))的元组,address为远程服务端地址,返回值是发送的字节数。
s.close()- 关闭套接字。
s.getpeername()- 返回连接套接字的远程地址,返回值通常是元组(ipaddr,port)。
s.getsockname()- 返回套接字自己的地址,通常是一个元组(ipaddr,port)。
s.setsockopt(level,optname,value)- 设置给定套接字选项的值。
s.getsockopt(level,optname[.buflen])- 返回套接字选项的值。
s.settimeout(timeout)- 设置套接字操作的超时时间,timeout是一个浮点数,单位是秒
s.gettimeout()- 返回当前超时期的值,单位是秒,如果没有设置超时期,则返回None。
s.fileno()- 返回套接字的文件描述符。
s.setblocking(flag)- 如果flag为0,则将套接字设为非阻塞模式,否则将套接字设为阻塞模式(默认值)。非阻塞模式下,如果调用recv()没有发现任何数据,或send()调用无法立即发送数据,那么将引起socket.error异常。
s.makefile()- 创建一个与该套接字相关连的文件。
原文链接:https://blog.csdn.net/weixin_43750377/article/details/111590893
网络传输使用的是utf-8传输,值得注意的是,数字是不可编码的,只能对字符串编码。
以前写的案例。。用的面向对象写的可能有点繁琐,不过还是能作为一个案例有助于理解的。。。
因为我用面向过程写的时候不知道哪出错了,一直报错,然后用面向对象来好找错。。。
服务端
import socket class intnet: def set_infor(self,name,ip,port): #设置端口信息 self.name=name self.ip=ip self.port=port def cont(self,conn): #与客户端连接 self.name=socket.socket() self.name.bind((self.ip,9001)) self.name.listen(1) self.conn=conn self.conn, addr = self.name.accept() print('对方已成功连接') def acpt_and_send(self,): #本方法用于两端之间来回的对话 while True: data=self.conn.recv(1024) if data.decode('utf-8')=='/exit': print('对方已退出聊天') break print('对方消息:'+data.decode('utf-8')) my_infor=input('==>') self.conn.sendall(my_infor.encode('utf-8')) def exit(self): #用于关闭服务器 self.conn.close() self.name.close() print('服务器已经关闭') if __name__=="__main__": sever=intnet() sever.set_infor('our','127.0.0.1',9002) sever.cont('用户1') sever.acpt_and_send() sever.exit()
客户端代码:
import socket class intnet: def set_infor(self,name,ip,port):#本部分用于配置连接的服务端的IP等 self.name=name self.ip=ip self.port=port def cont(self): #本方法用于连接服务端 self.name=socket.socket() self.name.connect(('127.0.0.1',9001)) print('连接成功,当前可正常通信') print('如果想要结束聊天,请输入/exit') def send_acept(self): #此部分用于两端相互对话 while True: my_infor=input('==>') self.name.sendall(my_infor.encode('utf-8')) if my_infor=='/exit': self.name.sendall('/exit'.encode('utf-8')) break infor=self.name.recv(1024) print(infor.decode('utf-8')) def exit(self): #结束聊天 self.name.close() print('您已退出聊天') if __name__=="__main__": user=intnet() user.set_infor('user','127.0.0.1',9002) user.cont() user.send_acept() user.exit()
直接复制到python就可以感受一下小小的聊天了。
先开启服务端在开启客户端。