当前位置:   article > 正文

Python网络通信--socket编程_socket 发送wifi数据包

socket 发送wifi数据包

 

原文链接:http://www.juzicode.com/archives/819

在前面的系列文章中涉及的内容都是在本地进行的,接下来介绍的内容会更有趣,会进入到一个更广阔的世界。Python中内置的socket模块可以实现多台电脑间通过网口进行通信,互相收发消息,这篇文章将从最底层的socket模块开始介绍,而更上层的ftplib,telnetlib等都是基于socket封装的更高层应用的模块。

提到socket通信,必然绕不开C/S结构,在C/S结构中,其中一台电脑作为server端,等待其他的client端连接、通信。比如一个Ftp服务器启动后,会等待其他的客户端连接、传输文件。一个Telnet服务端也是这样,开启telnet服务后,等待其他的客户端连接、登录、发送命令。

 

1、TCP连接

利用socket编程的模型和C/S结构的特点有关,在服务端:打开某个端口,监听来自客户端的请求连接,完成连接后就可以等待客户端发消息或者像客户端发送消息。在客户端:在某个端口去连接服务端,如果连接成功,就可以向服务端发送消息或者等待服务端发送消息。

服务端

在服务端首先创建一个ipv4的tcp连接实例,参数socket.AF_INET, socket.SOCK_STREAM分别代表IPV4和TCP连接:

  1. #创建socket服务端实例
  2. skt = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

接下来绑定ip和端口,这里我们使用本机地址127.0.0.1进行实验,端口可以选择非周知端口,这里选择19200,

  1. #绑定端口
  2. skt.bind(('127.0.0.1',19200))

然后在该端口上开始监听,接收来自客户端的消息,listen方法的入参100表示最多可以同时接收100个客户端进行连接:

  1. #监听端口
  2. skt.listen(100)

完成前面3个步骤,就可以用accept方法等待客户端进行连接,如果有客户端连接上,就会创建一个针对该客户端的connet实例,后面与客户端的通信就使用该 connet 实例完成,需要注意的是这里调用send,recv方法不再是前面创建服务端socket实例,而是accept方法创建的 connet 实例。在这个例子中约定了服务端等待客户端发送消息,并将客户端发来的消息发送回去,如果客户端关闭了连接,这个 connet 实例也将关闭:

  1. while True:
  2. #等待连接
  3. print('\n等待连接......')
  4. connet, address = skt.accept()
  5. print('客户端地址:%s,建立连接' % str(address))
  6. print('connet实例: ',connet)
  7. while True:
  8. #等待消息
  9. data = connet.recv(1024)
  10. msg = data.decode('utf8')
  11. print('客户端地址:%s,消息内容:%s' %(str(address),msg) )
  12. if not data:
  13. break
  14. #回显消息给客户端
  15. connet.send(data)
  16. time.sleep(0.5)
  17. #关闭连接
  18. connet.close()
  19. print('客户端地址:%s,连接关闭' % str(address))

 

客户端

在客户端也是一样首先创建一个socket实例 :

  1. #创建socket实例
  2. skt = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

第二步是根据ip和端口连接服务器:

  1. # 建立连接:
  2. skt.connect(('127.0.0.1', 19200))

接下来就是根据和服务端约定的通信流程,客户端每次发送一条消息,并等待服务端返回一条消息,当客户端发送结束后,关闭该socket连接:

  1. current_time=time.asctime()
  2. msg_list = [current_time,'juzicode.com', '微信公众号:桔子code', 'Socket通信']
  3. for msg in msg_list:
  4. # 发送消息:
  5. data_tx = bytes(msg,encoding='utf8')
  6. skt.send(data_tx)
  7. # 接收消息:
  8. data_rx = skt.recv(1024)
  9. print('接收到消息:%s'%( data_rx.decode('utf8')))
  10. time.sleep(0.5)
  11. #退出
  12. skt.close()

注意在客户端的send和recv方法直接使用的是创建的socket实例,而不是像服务端那样使用的是accept方法创建的连接实例。

 

在cmd下先运行server端程序,再运行client端程序,效果是这样的:

 

从上图可以看出,客户端每次通信的端口是不确定的,使用的端口号实际由系统分配空闲的端口号。

 

2、UDP连接

udp连接是一种面向无连接的通信方式,所以udp方式的通信相对于tcp通信,在服务端不需要使用listen方法在端口上连接,也不需要accept方法等待客户端发起连接,而是直接使用recvfrom方法接收消息或者sendto方法发送消息。

同样在客户端,也不需要使用connnet方法先与服务端建立连接,而是可以直接使用sendto或者recvfrom方法收发消息。

服务端

创建socket实例时,使用socket.SOCK_DGRAM参数创建UDP连接实例,并使用bind绑定端口:

  1. #创建socket服务端实例
  2. skt = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
  3. #绑定端口
  4. skt.bind(('127.0.0.1',19200))

使用recvfrom方法,可以返回获取到的消息和对端的地址信息,该地址信息就能用于sendto方法传入ip地址和端口号。因为udp不是面向连接的通信方法,所以其socket实例创建好之后并没有包含地址信息,这样不能直接使用send方法发送消息。当然仍然可以使用recv方法接收消息,这一般用于客户端,这时候客户端是已知服务端的ip地址和端口号的,并不需要像服务端那样使用recvfrom方法来获取对端通信的ip地址和端口号。

  1. while True:
  2. #等待消息
  3. data,address = skt.recvfrom(1024)
  4. msg = data.decode('utf8')
  5. print('客户端地址:%s,消息内容:%s' %(str(address),msg) )
  6. if not data:
  7. break
  8. #回显消息给客户端
  9. skt.sendto(data,address)
  10. time.sleep(0.5)

因为不需要建立连接,sever端发送和接收数据的使用的是socket实例,而不是像tcp连接那样使用的是connet连接实例。

 

客户端

创建socket实例的方法同服务端一样:

  1. #创建socket实例
  2. skt = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)

仍然是约定客户端发送一条消息,等待服务端返回一条消息,这里不需要connect方法和服务端“建立连接”。

  1. current_time=time.asctime()
  2. msg_list = [current_time,'juzicode.com', '微信公众号:桔子code', 'Socket通信']
  3. for msg in msg_list:
  4. # 发送消息:
  5. data_tx = bytes(msg,encoding='utf8')
  6. skt.sendto(data_tx, ('127.0.0.1',19200))
  7. # 接收消息:
  8. data_rx = skt.recv(1024)
  9. print('接收到消息:%s'%( data_rx.decode('utf8')))
  10. time.sleep(0.5)
  11. #退出
  12. skt.close()

 

启动sever端后,运行client端:

 

这篇文章介绍了利用socket编写服务端和客户端完成简单通信的例子,利用socket编程,需要用户设计应用层协议,更加灵活但是难度也更大。tcp方式通信是面向连接的,所以创建连接后每次发送数据并不需要指定对方的ip地址和端口号,而udp方式通信每次发送数据必须指定对方的ip地址和端口号。

 


关注"桔子code"后台回复"python教程",就可以获得Python桔子教程的全套源码了。

 

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/笔触狂放9/article/detail/791274
推荐阅读
相关标签
  

闽ICP备14008679号