在任何类型的通信开始之前,网络应用程序必须创建套接字
套接字地址:主机-端口对
如果套接字像一个电话插孔 - 允许通信的一些基础设施,那么主机名和端口号就像区号和电话号码的组合。然而拥有硬件和通信的能力本身并没有任何好处,除非你知道打电话给谁以及怎么打电话。
除此之外,还必须说明另外一端有人接听,否则就会出现:您所拨打的电话是空号,请核对后再拨
就像平时我们浏览网页看到的服务器没有响应或者404。
有效的端口号为0-65535(小于1024的端口号预留给了系统)
开始实例吧
首先我们要创建套接字必须使用socket.socket()函数,一般语法如下:
socket(socket_family, socket_type, protocol=0)
其中socket_family是AF_UNIX或者AF_INET,socket_type是SOCK_STREAM或SOCK_DGRAM,protocol通常省略,一般为0。
AF_UNIX是基于文件的套接字,AF_UNIX在编程的时候并不是太常用。
AF_INET用于基于网络的Socket。还有一个地址家族
AF_INET6, 用于IPv6。其实还有一些其他地址家族, 哪些要么是专业的, 过时的, 很少使用的, 要么是仍未实现的.
在所有的地址家族中,
AF_INET是使用最广泛的。



客户端程序如下
from socket import *
# 客户端准备连接的服务器的地址
HOST = '192.168.3.128'
# 服务器的端口号,保持一致
PORT = 9999
# 服务器的地址
ADDR = (HOST, PORT)
# 客户端缓冲区的大小(单位字节)
BUFSIZE = 1024
# 所有的套接字都使用 socket 函数来创建
tcpCliSock = socket(AF_INET, SOCK_STREAM)
# 客户端去连接服务器
tcpCliSock.connect(ADDR)
while True:
# 从键盘读取数据
data = input('发送消息:')
if not data:
break
# 给服务器发送消息. 由于 send 只能发送字节数据,所以把字符串编码之后再发送
tcpCliSock.send(data.encode('utf-8'))
# 接受服务器发送来的信息
data = tcpCliSock.recv(BUFSIZE)
if not data:
break
# 由于通过网络传递过来的其实是字节数据, 解码之后再输出
print(data.decode('utf-8'))
tcpCliSock.close()
服务端代码如下
from socket import *
# 服务器要绑定的主机地址,服务器端可为空
HOST = ''
PORT = 9999 # 服务器要监听的端口号
ADDR = (HOST, PORT)
BUFSIZE = 1024 # 设置服务器的缓冲区大小
while True:
tcpSevSock = socket(AF_INET, SOCK_STREAM) # 创建 socket 对象
tcpSevSock.bind(ADDR) # 把 socket 绑定到指定的地址和端口
tcpSevSock.listen(5) # 开启服务器监听器
print('等待客户端连接...')
tcpCliSock, cliAddress = tcpSevSock.accept() # 接受客户端的连接
print('客户端连接成功:', cliAddress)
while True:
try:
data = tcpCliSock.recv(BUFSIZE) # 接受客户端发来的数据
except:
print("接收出错")
break
# 如果没有数据
if not data:
# 跳出循环
break
# 把接收到字节数据解码
data = data.decode('utf-8')
print('收到信息:', data)
senddata = input('回复信息:')
# 编码发送
tcpCliSock.sendall(senddata.encode('utf-8'))
# 关闭客户端
tcpCliSock.close()
print('有一个客户端下线了...')
# 关闭服务器
tcpSevSock.close()
运行时,需要先运行服务端代码,再运行客户端代码!
效果:


















