socket模块

原文出处:https://blog.csdn.net/qq_26105397/article/details/90814836
版权声明:本文为一颗简单的心原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
1、socket模块的tcp通信编程。

import socket

class TcpSer:
    def __init__(self,ip,port):
        self.ip_ = ip
        self.port_ = port
        self.addr_ = (self.ip_,self.port_)
        # AF_INET:使用 IPv4 进行通信
        # SOCK_STREAM:是有保障的(即能保证数据正确传送到对方)面向连接的SOCKET
        self.tcpSock = socket.socket(socket.AF_INET,socket.SOCK_STREAM)

    def Bind(self):
        self.tcpSock.bind(self.addr_)
  
    
    def Listen(self):
        Ret = self.tcpSock.listen(0)
        return Ret

    def Accept(self):
        sock,addr = self.tcpSock.accept()
        return (sock,addr)
    
    def Run(self):
        print('Waiting a client connect tcpser ...')
        recMsgSize = 1024
        while True:
            clisock,cliaddr = self.Accept()
            recMsg = clisock.recv(recMsgSize).decode('utf-8')
            print('Recv from %s message:%s' %(cliaddr,recMsg))
            clisock.send(recMsg.encode('utf-8'))
    
    def closeSock(self):
        self.tcpSock.close()

if __name__ == "__main__":
    try:
        ip = input('ip:')
        port = int(input('port:'))
        tcpser = TcpSer(ip,port)
        tcpser.Bind()
        tcpser.Listen()
        tcpser.Run()
    except KeyboardInterrupt:
        tcpser.closeSock()

client.py:
import socket
import time

ip = '192.1680.102'
port = 8000

addr = (ip,port)

cfd = socket.socket(socket.AF_INET,socket.SOCK_STREAM)

cfd.connect(addr)

while True:
	try:
		message = input('>>>')
		cfd.send(message.encode('utf-8'))
	except:
		cfd.close()        

以上是简单的tcp服务连接通信,tcp是面向连接,双方要想通信必须要进行连接;
tcp通过内部通过三次握手进行具体的连接,并且在tcp通信过程中,可以确保数据的准确性,一般可以通过双方相互之间通过发送数据与接收确认数据包,来保证数据的传输。

并且在tcp中,如果数据包过大,内核中会将数据包拆分开始进行发送,并且按照
mtu(Maximum Transmission Unit,缩写MTU,中文名是:最大传输单元。)大小进行发送,每个数据包都有序列号,以及校验和。目的是为了确保所有的数据包发送过去之后,另外一方通过将对应的序列号拿出来,重新拼接成一个完成的数据包。

除此之外,tcp设置重传机制,数据包在传输的过程,可能会出现网络问题,再试数据包丢失,或者延时发送,重传机制就是为保证这个。具体的可根据实际情况,编写者,也可自己实现对应的确认包,以保证双方通信正常。

在tcp传输过程遇到的最大的问题就是粘包问题,在实际编写代码通信的时候,可根据自定义相关的数据包,确定数据包的大小,双方进行相互约束,达成一致的标准,进行具体的分析,从而实现处理解决粘包问题。

反观udp(用户数据报协议:给应用程序发送数据包功能并允许它们在所需的层次上架构自己的协议)是非面向连接的,udp每次发送的是一个完整的数据包体。因为非面向连接,所以不保证数据包一定发送至目标。编写者可根据实际情况,自行实现对应的两端包括机制,从而实现类似tcp重传的机制,确保数据发送至目标端。

是否需要这样的机制,根据实际业务来决定即可。另外在tcp通信过程中,要避免出现大量的time_wait的连接等待,如果出现大量,可能会导致服务资源被占用消耗殆尽,其他的客户端可能就不能正常连接,具体的处理方法,请参考博主的其他博文有所接收。

2、udp通信过程:

from socket import *
from time import ctime

host = '' #监听所有的ip
port = 13141 #接口必须一致
bufsize = 1024
addr = (host,port) 

udpServer = socket(AF_INET,SOCK_DGRAM)
udpServer.bind(addr) #开始监听

while True:
    print('Waiting for connection...')
    data,addr = udpServer.recvfrom(bufsize)  #接收数据和返回地址
    #处理数据
    data  = data.decode(encoding='utf-8').upper()
    data = "at %s :%s"%(ctime(),data)
    udpServer.sendto(data.encode(encoding='utf-8'),addr)
    #发送数据
    print('...recevied from and return to :',addr)

udpServer.close()

同样客户端可使用如上的客户端代码,去掉连接方法即可。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值