python------网络编程

一、多线程版

server.py

import socket
from threading import Thread
import re
import time
"""
socket.socket(family=AF_INET, type=SOCK_STREAM, proto=0, fileno=None)
    family:choose one from [
        AF_UNIX  ——————————   unix本机之间进行通信
        AF_INET  ——————————    使用IPv4
        F_INET6  ——————————     使用IPv6
    type:
        SOCK_STREAM          # TCP套接字类型
      SOCK_DGRAM   # UDP套接字类型
      SOCK_RAW               #原始套接字类型,这个套接字比较强大,创建这种套接字可以监听网卡上的所有数据帧
      SOCK_RDM              #是一种可靠的UDP形式,即保证交付数据报但不保证顺序。SOCK_RAM用来提供对原始协议的低级访问,在需要执行某些特殊操作时使用,如发送ICMP报文。SOCK_RAM通常仅限于高级用户或管理员运行的程序使用。
setsockopt(level,optname,value)
    level:通常情况下是SOL_SOCKET,意思是正在使用的socket选项。
    optname:
        SO_BINDTODEVICE:可以使socket只在某个特殊的网络接口(网卡)有效。也许不能是移动便携设备
        SO_BROADCAST:允许广播地址发送和接收信息包。只对UDP有效。如何发送和接收广播信息包
        SO_DONTROUTE:禁止通过路由器和网关往外发送信息包。这主要是为了安全而用在以太网上UDP通信的一种方法。不管目的地址使用什么IP地址,都可以防止数据离开本地网络
        SO_KEEPALIVE:可以使TCP通信的信息包保持连续性。这些信息包可以在没有信息传输的时候,使通信的双方确定连接是保持的
        SO_OOBINLINE:可以把收到的不正常数据看成是正常的数据,也就是说会通过一个标准的对recv()的调用来接收这些数据
        SO_REUSEADDR:当socket关闭后,本地端用于该socket的端口号立刻就可以被重用。通常来说,只有经过系统定义一段时间后,才能被重用。
"""

def funcThread(sock,addr):
    print("a new link from ip:%s" % addr[0])
    sock.send(b"welcome")
    while(True):
        data=sock.recv(1024)
        print(data,end=" ")
        time.sleep(1)
        print(not data)
        if(not data):
            break
        sock.send(("hello,%s" % data.decode("utf-8")).encode("utf-8"))
    sock.close()


#创建tcp套接字,
s=socket.socket(socket.AF_INET, socket.SOCK_STREAM)

s.setsockopt(socket.SOL_SOCKET,socket.SO_REUSEADDR,1)
s.bind(("127.0.0.1",8000))
s.listen(10)
while(True):
    sock,addr=s.accept()
    print(addr)
    t=Thread(target=funcThread,args=(sock,addr))
    t.start()

client.py

import socket

s=socket.socket(socket.AF_INET,socket.SOCK_STREAM)
s.connect(("127.0.0.1",8000))
print(s.recv(1024).decode("utf-8"))
info=["josh","bob","silly","jane"]
for data in info:
    s.send(data.encode("utf-8"))
    print(s.recv(1024))
s.send("".encode("utf-8"))
s.close()

二、单进程非堵塞

服务器:

import socket
from threading import Thread
import re
import time

#创建tcp套接字,
s=socket.socket(socket.AF_INET, socket.SOCK_STREAM)
#设置socket为非堵塞
s.setblocking(False)
s.setsockopt(socket.SOL_SOCKET,socket.SO_REUSEADDR,1)
s.bind(("127.0.0.1",8000))
s.listen(10)
socket_list=[]
while(True):
    try:
        client_sock,addr=s.accept()
        client_sock.setblocking(False)
        #将接入的客户端也设置为非堵塞
    except Exception as e:
        pass
    else:
        # print(addr)
        print("a new socket(%s,%s) is coming" % addr)
        socket_list.append((client_sock,addr))
    for sock,addr in socket_list:
        try:
            data=sock.recv(1024).decode('utf-8')
        except Exception as e:
            pass
        else:
            if(data==""):
                print("(%s)has gone" % str(addr))
                sock.close()
                socket_list.remove((sock,addr))
            else:
                print("(%s)" % (data,))
                partern=re.compile(r'\d')
                res=partern.findall(data)
                sock.send((res[0]+"你好,我已收到你的第"+res[1]+"次发送的数据").encode("utf-8"))


客户端

import socket
from threading import Thread


def fun1(n):
    s=socket.socket(socket.AF_INET,socket.SOCK_STREAM)
    s.connect(("127.0.0.1",8000))
    for i in range(n):
        try:
            data="我是线程:(%s),这是我第(%s)次发送数据。"%(n,i)
            s.send(data.encode("utf-8"))
            print(s.recv(1024).decode('utf-8'))
        except Exception as e:
            pass
    s.send("".encode("utf-8"))
    s.close()


for i in range(10):
    t=Thread(target=fun1,args=(i,))

    t.start()

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值