提示:以下是本篇文章正文内容,下面案例可供参考
一、TCP/IP简介
通信双方必须知道对方的标识。互联网上计算机的唯一标识就是IP地址。通常是网卡。 IP 协议负责把数据从一台计算机通过网络发送到另一台计算机上。数据被分割成一小块,然后通过IP包发送过去。 IP包的特点是按快发送,途径多个路由,但不保证能到达,也不保证顺利到达。 IP地址实际上是一个32位整数(IPv4),以字符串表示的IP地址实际上是把32位整数按8位分组后的数字表示(如192.165.0.1),目的是便于阅读。 TCP协议是建立在IP协议之上的,TCP协议负责在两台计算机之间建立可靠连接,保证数据顺利到达。 一个IP包除了包含传输的数据外,还包含源IP地址和目标IP地址,源端口和目标端口。 而端口的作用是区分送过来的IP包是给那个程序的。
二、网络设计模块
1.Socket简介
网络编程中有一个基本组件----套接字(socket) 套接字为特定的网络协议(如TCP/IP,UDP/IP)套件对上的网络应用程序提供当前可移植标准的对象。套接字允许程序接收数据并进行连接,为了建立通信通道,网络通信的每个端点拥有一个套接字对象级为重要。
2、python中的socket模块,使用该模块建立服务器需要6个步骤。
1.创建socket对象。
该处使用socket()函数来创建套接字。 语法格式
socket.socket([family[,type[,protoco]]])
- family :可以是AF_UNIX(用于同一台机器上的进程间通信),也可以是AF_INET(对于IPV4协议的TCP和UDP),或AF_INET6(用于TPV6)
- type:套接字类型可以根据面向连接和非连接分为SOCK_STREAM(流套接字)或 SOCK_DGRAM(非流套接字)。
- protoco:一般不填,默认为0.
2.将socket绑定(指派)到指定地址上。
socket.bind(address)
address 必须是一个双元素元组。参数为主机名或ip地址加端口。
3.绑定后必须准备好套接字,以便接收连接。
请求方式如下:
socket.listen(backlog)
backlog 用于指定最多连接数,至少为一。接到连接请求后,这些请求必须排队,如果已满,就拒绝请求。
4.服务器套接字通过socket的accept 方法等待客户请求一个连接。
调用accept方法时,socket会进入等待(或阻塞)状态。客户请求连接时,accept方法建立连接并返回服务器。accept方法返回一个含有两个元素的元组,如(connection,address)。第一个元素(connection)是新的socket对象,服务器通过它与客户通信;第二个元素(address)是客户的互联网地址。
5.处理阶段,服务器和客户通过send和reext方法通信(传输数据)。
服务器调用send,并采用字符串形式向客户发送信息。send方法返回已发送的字符个数。服务器使用recy方法从客户接收信息。调用reev时,必须指定一个整数控制本次调用所接收的最大数据量。recy方法在接收数据时会进入blocket状态,最后返回一个字符串,用于表示收到的数据。如果发送的量超过recy允许的量,数据就会被截断。多余的数据将缓冲于接收端。以后调用recy时,多余的数据会从缓冲区删除。
6.传输结束,服务器调用socket的close方法以关闭连接。
代码案列
import socket
import threading
import time
def socket_server():
server_socket=socket.socket(socket.AF_INET,socket.SOCK_STREAM)
host = socket.gethostname()
port = 5555
server_socket.bind((host,port))
server_socket.listen(5)
while True:
sock,addr = server_socket.accept()
t = threading.Thread(target = tcp_link,args = (sock,addr))
t.start()
def tcp_link(sock,addr):
print('Accept new connection from %s:%s...'% addr)
sock.send('欢迎学校 Python 网络编程!'.encode('utf-8'))
while True:
data = sock.recv(1024)
time.sleep(1)
if not data or data.decode('utf-8')=='exit':
break;
sock.send(("Hello,%s!"%data.decode('utf-8')).encode('utf-8'))
sock.close()
print('connection from %s:%s closed.'%addr)
def main():
socket_server()
if __name__ =='__main__':
main()
3、python中的socket模块,使用该模块建立客户连接需要4个步骤。
1.创建一个socket以连接服务器。socket=socket.socket(family,type) 2.使用socket 的connect 方法连接服务器。 socket.connect((hoat,port)) 3.通过send()与recv()方法通信。 4.结束后,调用socket的close方法以关闭连接。
代码案列:
import socket
def socket_client():
s=socket.socket(socket.AF_INET,socket.SOCK_STREAM)
host = socket.gethostname()
port = 5555
s.connect((host,port))
print(s.recv(1024).decode('utf-8'))
for data in ['小青','小白','小花']:
s.send(data.encode('utf-8'))
print(s.recv(1024).decode('utf-8'))
s.send(b'exit')
s.close()
def main():
socket_client()
if __name__ =='__main__':
main()
如何知道服务器端口
1.域名可以自动转换到IP地址。 2.作为服务器,提供服务时端口号必须固定下来。由于我们想要访问网页,因此新浪提供网页服务的服务器必须把端口号固定在80端口。80端口是Web服务的标准端口。其他服务都有对应的标准端口号,如SMTP服务是25端口,FTP服务是21端口,等等。端口号小于1024的是Internet标准服务端口,端口号大于1024的可以任意使用,
## 4、socket 的一些套接字函数。 ### 服务器端。
函数 | 描述 |
---|
bind() | 绑定地址(host,port)到套接字, 在AF_INET下,以元组(host,port)的形式表示地址。 | listen() | 开始TCP监听。backlog指定在拒绝连接之前,操作系统可以挂起的最大连接数量。该值至少为1,大部分应用程序设为5就可以了。 | accept() | 被动接受TCP客户端连接,(阻塞式)等待连接的到来 |
客户端。
函数 | 描述 |
---|
connect() | 主动初始化TCP服务器连接,。一般address的格式为元组(hostname,port),如果连接出错,返回socket.error错误。 | connect_ex() | connect()函数的扩展版本,出错时返回出错码,而不是抛出异常 |
公共用途。
函数 | 描述 |
---|
recv() | 接收TCP数据,数据以字符串形式返回,bufsize指定要接收的最大数据量。flag提供有关消息的其他信息,通常可以忽略。 | send() | 发送TCP数据,将string中的数据发送到连接的套接字。返回值是要发送的字节数量,该数量可能小于string的字节大小。 | sendall() | 完整发送TCP数据,完整发送TCP数据。将string中的数据发送到连接的套接字,但在返回之前会尝试发送所有数据。成功返回None,失败则抛出异常。 | recvfrom() | 接收UDP数据,与recv()类似,但返回值是(data,address)。其中data是包含接收数据的字符串,address是发送数据的套接字地址。 | sendto() | 发送UDP数据,将数据发送到套接字,address是形式为(ipaddr,port)的元组,指定远程地址。返回值是发送的字节数。 | close() | 关闭套接字 | getpeername() | 返回连接套接字的远程地址。返回值通常是元组(ipaddr,port)。 | getsockname() | 返回套接字自己的地址。通常是一个元组(ipaddr,port) | setsockopt(level,optname,value) | 设置给定套接字选项的值。 | getsockopt(level,optname[.buflen]) | 返回套接字选项的值。 | settimeout(timeout) | 设置套接字操作的超时期,timeout是一个浮点数,单位是秒。值为None表示没有超时期。一般,超时期应该在刚创建套接字时设置,因为它们可能用于连接的操作(如connect()) | gettimeout() | 返回当前超时期的值,单位是秒,如果没有设置超时期,则返回None。 | fileno() | 返回套接字的文件描述符。 | setblocking(flag) | 如果flag为0,则将套接字设为非阻塞模式,否则将套接字设为阻塞模式(默认值)。非阻塞模式下,如果调用recv()没有发现任何数据,或send()调用无法立即发送数据,那么将引起socket.error异常。 | makefile() | 创建一个与该套接字相关连的文件 |
# SocketTool 编程调试工具 参考博文:[添加链接描述](https://blog.csdn.net/xuzhexing/article/details/90763756?ops_request_misc=%257B%2522request%255Fid%2522%253A%2522162717578716780274151128%2522%252C%2522scm%2522%253A%252220140713.130102334..%2522%257D&request_id=162717578716780274151128&biz_id=0&utm_medium=distribute.pc_search_result.none-task-blog-2~all~top_positive~default-1-90763756.first_rank_v2_pc_rank_v29&utm_term=python%E7%BD%91%E7%BB%9C%E7%BC%96%E7%A8%8B&spm=1018.2226.3001.4187) 工具:SocketTool 1.下载链接: [添加链接描述](http://www.xitongzhijia.net/soft/110847.html) 也可以到百度上搜。
2.在左侧有tcp和udp的客户端或服务端的快捷按钮,上方有【创建】【删除】【退出】等选项按钮。 4 我们先来建立TCP的测试服务端。点击【TCP Server】再点击【创建】。 选择一个监听端口,这里我们使用6001作为服务端的监听端口。 建立完成后,服务端会自动启动,软件会显示【启动监听】的状态。 建立完成后,服务端会自动启动,软件会显示【启动监听】的状态。 [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传 我们可以检测一下本机的6001端口是否已经打开。在DOS窗口中输入命令【netstat -a】,可以在列表中看到本机的6001端口的状态为listening的状态,表示本机的6001端口正处于监听的状态。 在DOS窗口中输入命令【telnet 192.168.0.140 6001】来登录本地的6001端口。 注意:192.168.0.140 6001 要根据软件中本机的编号来写。 window下 无法执行 telnet 命令的解决方法 1.打开设置中应用。 2.打开右上角的 3. 4.找到telnet 服务,勾选就好
点击回车键,就可以成功登录6001端口。在测试软件中就可以看到状态是已连接的状态,同时也可以看到对方的ip就是本地ip。
在软件的发送窗口中输入1234567890,点击发送后,在DOS窗口中就可以看到软件发送过来的数据了。 若想发送中文不要勾选16进制。
|