zoukankan      html  css  js  c++  java
  • Python的网络编程[0] -> socket[2] -> 利用 socket 建立 TCP/UDP 通信

    Socket


     目录

    1. socket 的 TCP/IP 通信基本建立过程
    2. socket 的 UDP 通信基本建立过程
    3. socket 的 UDP 广播式通信基本建立过程
    4. socket 的多线程通信建立过程

      

    1 socketTCP/IP通信基本建立过程

    socket的TCP/IP通信连接主要包括两个部分,服务端与客户端

    1.1 Socket server服务端建立

    服务端建立步骤主要有:

    1. 初始化IP地址和端口号;
    2. 生成socket实例,TCP/IP通信选择AF_INET(IPV4),SOCK_STREAM(流套接字类型,数据像字符流一样通过);
    3. bind()函数绑定IP和端口,listen()函数设置最大监听数量;
    4. accept()函数接收client的连接,对于连接的client返回2个参数cs,addr,cs为一个新生成的socket类,用于与连接的client进行通讯,addr包含IP和端口号信息;
    5. 基于生成的cs与client进行通讯。
     1 # server
     2 
     3 import socket
     4 # set IP and Port
     5 address = ('127.0.0.1', 31500)
     6 # choose IPV4, stream type
     7 s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
     8 # bind address and ip
     9 s.bind(address)
    10 # allow max five connection
    11 s.listen(5)                                             
    12 
    13 while True:
    14     # wait client's request, cs is a new socket object and server use it to communicate with client
    15     cs, address = s.accept()                            
    16     print('got connected from', address)
    17     # send message to client
    18     cs.send(b'hello I am server, welcome')
    19     # receive message from client and decode
    20     re = cs.recv(1024).decode('utf-8')                  
    21     print(re)
    22     cs.close()

    1.2 Socket client客户端建立

    客户端建立步骤主要有:

    1. 初始化IP地址和端口号;
    2. 生成socket实例,TCP/IP通信选择AF_INET(IPV4),SOCK_STREAM(流套接字类型,数据像字符流一样通过);
    3. connect()函数进行IP和端口连接(对应的服务端会利用accept()函数生成一个通信实例进行两者相互之间的通信);
    4. 利用send()函数和recv()函数开始通信。
     1 # client
     2 
     3 import socket
     4 
     5 address = ('127.0.0.1', 31500)
     6 s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
     7 # connect address to correct ip and port
     8 s.connect(address)                                      
     9 s.send(b'hello, I am client')
    10 data = s.recv(1024).decode('utf-8')
    11 print('the data received is', data)
    12 
    13 s.close()

    2 socketUDP通信基本建立过程

    socket的UDP通信连接主要包括两个部分,服务端与客户端

    2.1 Socket server服务器建立

    服务器建立步骤主要有:

    1. 设置端口号,ip地址可以为空字符(‘’),即表示接受任何地址来的数据报;
    2. 生成socket实例,UDP通信选择AF_INET(IPV4),SOCK_DGRAM(数据报套接字类型,数据以数据报datagrams通过);
    3. bind()函数绑定IP和端口;
    4. 利用recvfrom()函数进行数据接收,获得参数msg,addr,这两个参数分别为信息和客户端的地址,可根据收到的addr进行通信回复。
    1 import socket
    2 sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
    3 sock.bind(('', 5656))
    4 print('server ready')
    5 while True:
    6     msg, addr = sock.recvfrom(1024)
    7     print(msg, addr)
    8     sock.sendto(b'hi, this is server', addr)

    2.2 Socket client客户端建立

    客户端建立步骤主要有:

    1. 生成socket实例,UDP通信选择AF_INET(IPV4),SOCK_STREAM(数据报套接字类型,数据以数据报datagrams通过);
    2. 无需连接直接利用sendto函数向目标ip和端口发送数据;
    3. 利用recvfrom()函数接收服务端的数据。
    1 import socket
    2 sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
    3 sock.sendto(b'hi, this is client.', ('localhost', 5656))
    4 data, msg = sock.recvfrom(1024)
    5 print(data, msg)

    3 socketUDP广播式通信基本建立过程

    3.1 Socket broadcast server服务端建立

    服务端建立步骤主要有:

    1. 生成UDP的socket实例;
    2. 利用setsockopt设置socket的broadcast模式为True,地址复用(多个套接字可以同时连接一个端口上);
    3. bind()函数绑定IP和端口;
    4. 利用recvfrom()函数进行数据接收,获得参数msg,addr,这两个参数分别为信息和客户端的地址,可根据收到的addr进行通信回复
     1 import socket
     2 sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
     3 sock.setsockopt(socket.SOL_SOCKET, socket.SO_BROADCAST, True)
     4 sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, True)
     5 sock.bind(('', 5656))
     6 print('server ready')
     7 while True:
     8     msg, addr = sock.recvfrom(1024)
     9     print(msg, addr)
    10     sock.sendto(b'hi, this is server', addr)

    3.2 Socket broadcast client客户端建立

    客户端建立步骤主要有:

    1. 生成UDP的socket实例;
    2. 利用setsockopt设置socket的broadcast模式为True,地址复用(多个套接字可以同时连接一个端口上);
    3. 无需连接直接利用sendto函数以广播形式向<’broadcast’>和端口发送数据;
    4. 利用recvfrom()函数接收服务端的数据。
    1 import socket
    2 sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
    3 sock.setsockopt(socket.SOL_SOCKET, socket.SO_BROADCAST, True)
    4 sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, True)
    5 for i in range(5):
    6     sock.sendto(b'hi, this is client.', ('<broadcast>', 5656))
    7     data, msg = sock.recvfrom(1024)
    8     print(data, msg)

    4 socket的多线程通信的建立过程

    4.1 Socket thread server多线程服务端建立

    多线程服务器的服务器建立与前面相同,唯一不同之处在于accept函数返回新的通信socket后调用线程模块启动一个新的子线程进行通信。

    此处补充建立了一个单线程的服务端,最终结果可以看出单线程的服务端需等待程序再次循环至accept处才能继续下一个客户端的通信。

     1 from socket import *
     2 from threading import Thread
     3 
     4 class Service():
     5     def __init__(self):
     6         #self.ip = '192.168.121.100'
     7         #self.port = 2049
     8         self.ip = '127.0.0.1'
     9         self.port = 31500
    10         self.addr = (self.ip, self.port)
    11         self.serv = socket(AF_INET, SOCK_STREAM)
    12         self.serv.bind(self.addr)
    13 
    14         self.serv.listen(5)
    15 
    16     def run(self):
    17         while True:
    18             newServ, addr = self.serv.accept()
    19             Thread(target=self.chat, args=(newServ, )).start()
    20             
    21     def chat(self, newServ):
    22         i = 1
    23         while i <= 10:
    24             newServ.send('get data'.encode('utf-8'))
    25             ra = newServ.recv(1024).decode('utf-8')
    26             print(ra)
    27             #newServ.close()
    28             print('next')
    29             i += 1
    30 
    31 class Servicex(Service):
    32     def __init__(self):
    33         Service.__init__(self)
    34 
    35     def run(self):
    36         while True:
    37             newServ, addr = self.serv.accept()
    38             self.chat(newServ)
    39 
    40 #serv = Service()
    41 #serv.run()
    42 
    43 serv = Servicex()
    44 serv.run()

    4.2 Socket thread client多线程客户端建立

    多线程服务器的客户端建立与前面相同,不同之处在于生成了两个socket的实例,并用线程模块同时调用运行这两个socket通信实例进行通信。

     1 import socket
     2 import time
     3 from threading import Thread
     4 
     5 class Chamber():
     6     def __init__(self, tag):
     7         #self.ip = '192.168.121.100'
     8         #self.port = 2049
     9         self.ip = '127.0.0.1'
    10         self.port = 31500
    11         self.tag = tag
    12         self.addr = (self.ip, self.port)
    13         self.sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    14         self.sock.connect(self.addr)
    15 
    16     def getTemper(self):
    17         self.sock.send(('021?8E03'+self.tag).encode('utf-8'))
    18         time.sleep(2)
    19         print('Receive blocking', self.tag)
    20         data = self.sock.recv(1024)
    21         print(data)
    22         #self.sock.close()
    23 
    24     def run(self):
    25         for i in range(10):
    26             self.getTemper()
    27 
    28 cham_1 = Chamber('C_1')
    29 cham_2 = Chamber('C_2')
    30 Thread(target=cham_1.run).start()
    31 Thread(target=cham_2.run).start()

     

  • 相关阅读:
    windows内核中对于索引*4(内存)的一个反汇编知识点
    任务段与任务门
    中断门与陷阱门
    调用门
    Visual Studio 调试系列2 基本调试方法
    Visual Studio 调试系列1 Debug 与 Release 模式
    Visual Studio 调试(系列文章)
    C#各版本新增加功能(系列文章)
    C#8.0 中使用默认接口成员更新接口
    C#8.0 新增功能
  • 原文地址:https://www.cnblogs.com/stacklike/p/8118671.html
Copyright © 2011-2022 走看看