python 网络编程(socket)

网络协议三要素: 语法,语义,时序
常见应用层协议: ftp,http,smtp,pop3,tlnet…
传输层协议**: tcp,udp,端口号**
ip地址: ipv4 , ipv6
MAC地址:网卡地址(唯一的)

socket = ip : 端口号

udp适用于对效率要求较高而对准确性要求相对较低的场合,例如视频在线点播,网络语音通话

tcp 适用于对传输效率低 ,对准确性高的场合,列如文件传输,
需要建立连接,数据传输,断开连接三个步骤
在这里插入图片描述

1.创建服务器端套接字Socket,监听客户端的连接请求。
(1)通过socket()函数创建服务器端套接字Socket对象;
(2)Socket对象用bind()函数把服务器的IP地址绑定到这个套接字上;
(3)Socket对象用listen()函数监听客户端的连接请求;
(4)Socket对象用accept()函数等待并接收客户端的连接,连接成功则创建一个新的通信套接字。

2 创建客户端Socket对象,向服务器端发起连接
(1)通过socket()函数创建客户端Socket对象;
(2)客户端Socket对象用connect()函数发起连接请求。
(3)建立连接。
3. 客户机与服务器通信
(1)服务器通信套接对象用sendall()函数向客户端发送信息;
(2)客户端套接字Socket对象用recv()函数接收服务器发来的信息;
(3)客户端套接字Socket对象用sendall()函数向服务器发送信息;
(4)服务器通信套接字对象用recv()函数接收客户端发来的信息;
(5)通信完毕,使用close()函数关闭套接字。

在这里插入图片描述

在这里插入图片描述
例子

server  代码

from socket import *
HOST = '127.0.0.1'
PORT = 4321
ADDR = (HOST,PORT)
# socket()函数创建服务器端套接字Socket对象;
ss=socket(AF_INET,SOCK_STREAM,0)
# 用bind()函数把服务器的IP地址绑定到这个套接字上
ss.bind(ADDR)
# 用listen()函数监听客户端的连接请求;
ss.listen(10)
print('等待客户机连接......\n')
# accept()函数等待并接收客户端的连接,连接成功则创建一个新的通信套接字。
cs, caddr = ss.accept()
print('连接的客户机来自于', caddr)
str = '欢迎访问本服务器'
# 将数据返回给客户端
cs.sendall(bytes(str, 'UTF-8'))

while True:
    msg = cs.recv(1024).decode()
    print('接受客户机信息:', msg)
    send_msg = input("请输入返回给客户端的信息(quit跳过本次链接):")
    if send_msg == "quit":
        cs.sendall(bytes(" ", 'UTF-8'))
    else:
        cs.sendall(bytes(send_msg, 'UTF-8'))


ss.close()



client代码


from socket import *

HOST = '127.0.0.1'
PORT = 4321
ADDR = (HOST, PORT)
# 创建socket对象
cs = socket(AF_INET, SOCK_STREAM, 0)
# 获取服务器连接的信息 (是否成功)
cs.connect(ADDR)
data = cs.recv(1024).decode()
print("服务器返回的信息:",data)

while True:

    send_data = input("请输入要发送的数据:")
    # 发送的数据为空就返回
    if not send_data or send_data == 'quit':
        break
    cs.sendto(send_data.encode('utf-8'),ADDR)
    # 如果没有收到数据则会阻塞等待 直到收到数据
    msg = cs.recv(1024).decode()
    if msg==" ":
        print("服务器没有搭理你")
        continue
    # 1024表示本次接收的最大字节数

    print("服务器消息:",msg)

cs.close()




服务器自动回复tcp写法

server端

import random
import socket
from os.path import commonprefix

# 主机地址
HOST = '127.0.0.1'
# 开设端口
PORT = 8005

# 词库
words = {
    'hello': 'hello',
    '你好': '你好',
    'how are you?': 'Fine, thank you',
    'how old are you?': '20岁',
    'bye': 'bye',
    'python': ["考虑一千次,不如去做一次;犹豫一万次,不如实践一次;华丽的跌倒,胜过无谓的彷徨,将来的你,一定会感谢现在奋斗的你。",

               "没有所谓失败,除非你不再尝试。无论你昨晚经历了怎样的泣不成声,早上醒来这个城市依旧车水马龙。宁可笑着流泪,绝不哭着后悔。",

               "一朵花凋零荒芜不了整个春天,一次跌倒也荒废不了整段旅程。走下去,凭着耐心和拼搏,生活自会给予你全部答案",

               "行动,是打败焦虑的最好办法。当你不知道该做什么的时候,就把手头的每件小事都做好;当你不知道该怎么开始时,就把离你最近的那件事情做好!",

               "每天给自己一个希望,试着不为明天而烦恼,不为昨天而叹息,只为今天更美好!人生没有对错,只有选择后的坚持,不后悔,走下去,就是对的。走着走着,花就开了。",

               "宁愿跑起来被拌倒无数次,也不要规规矩矩走一辈子。就算跌倒也要豪迈的笑。",

               "不去追逐,永远不会拥有。不往前走,永远原地停留。知道自己目的地的人,才是旅行得最远的人。",
               "再长的路,一步步也能走完,再短的路,不迈开双脚也无法到达。行动是治愈恐惧的良药,而犹豫、拖延将不断滋养恐惧。",

               "对别人说狠话,不如对自己下狠手;扛得住艰难,才能配得上梦想;不想苦一辈子,就要苦一阵子!",

               "心在哪里,收获就在哪里。人这一生能力有限,但是努力无限。努力做一个善良的人,做一个心态阳光的人,做一个积极向上的人,用正能量激发自己,也感染身边的人。用最美的心情迎接每天的朝阳!你阳光,世界也会因你而光彩。",

               "如果真的不知道将来要做什么,索性就先做好眼前的事情。只要今天比昨天过得好,就是进步。长此以往,时间自然会还你一个意想不到的未来。",

               "生活不会按你想要的方式进行,它会给你一段时间,让你孤独、迷茫又沉默忧郁。等你度过低潮,那些独处的时光必定能照亮你的路,也是这些不堪陪你成熟。",

               "别人拥有的,你不必羡慕,只要努力,你也会拥有;自己拥有的,你不必炫耀,因为别人也在奋斗,也会拥有。",

               "你要明白很多时候,抱怨是没有用的,抱怨一天远没有努力一会的收获大。所以,努力吧!将所有的抱怨与不满都化作动力,强大给这个世界看!",

               "不到最后一刻,千万别放弃。最后得到好东西,不是幸运,有时候,必须有前面的苦心经营,才有后面的偶然相遇。"]
}

# AF_INET = ipv4 , SOCK_STREAM = tcp链接
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

s.bind((HOST, PORT))
# 监听一个客户端连接
s.listen(1)
print('监听端口:', PORT)

conn, addr = s.accept()
print('客户机已接入:', addr)
# 开始聊天

while True:
    data = conn.recv(1024).decode()
    if not data:
        break
    print('接收消息:', data)
    # 尽量猜测对方要表达的真正意思
    m = 0
    key = ""
    for k in words.keys():
        # 删除多余的空白字符串
        data = ' '.join(data.split())
        # 与某个键接近就直接返回 从第一个字符开始比较返回两个字符之间最长的字符
        if len(commonprefix([k, data])) > len(k) * 0.7:
            key = k
            break

        # 当第一个字符与之不匹配时或者小于70%这个度时 进入第二轮比较
        # set交集越长 说明匹配度越高
        length = len(set(data.split()) & set(k.split()))
        if length > m:
            m = length
            key = k

    # 鸡汤语录
    if key == 'python':
        index = random.randint(1, 15)
        conn.sendall(('心灵鸡汤:' + words.get('python')[index]).encode())
    else:
        conn.sendall(words.get(key, 'sorry').encode())

conn.close()
s.close()

client端

import socket
import sys

# 服务端主机ip地址和端口号
HOST = '127.0.0.1'
PORT = 8005

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

try:
    # 连接服务器
    s.connect((HOST, PORT))
except Exception as e:
    print('服务器还没开启.....')
    sys.exit()
while True:
    c = input('请输入发送的内容:')
    s.sendall(c.encode())
    # 从服务端接收数据
    data = s.recv(1024)
    data = data.decode()
    print('收到消息:', data)
    if c.lower() == 'bye':
        break
# 关闭连接
s.close()

在这里插入图片描述

在这里插入图片描述


server

import socket
from datetime import datetime

# 使用ipv4, UDP协议传数据
s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)

s.bind(('', 5005))

while True:
    data, addr = s.recvfrom(1024)
    # 显示接收到消息
    print('received message:{0} from {1}'.format(data.decode(), addr))
    if data == b'ask for time':
        now = str(datetime.now())[:19]
        s.sendto(now.encode(), addr)

s.close()

client

import socket
import time

while True:
    s = socket.socket(socket.AF_INET,socket.SOCK_DGRAM)
    s.sendto(b'ask for time',('0.0.0.0',5005))
    data,addr = s.recvfrom(1024)
    print(data.decode())
    s.close()
    time.sleep(2)

==================================================================
服务器自动回复udp写法

server端写法

import socket
from os.path import commonprefix

HOST = '127.0.0.1'
PORT = 8085

words = {

    'how are you?': 'Fine, thank you',
    'how old are you?': '20',
    'bye': 'bye'
}

# AF_INET = ipv4 , SOCK_DGRAM = UDP链接
s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)

s.bind((HOST, PORT))

# 开始聊天

while True:
    data,addr = s.recvfrom(1024)
    data = data.decode()
    if not data:
        break
    print(addr,':', data)
    # 尽量猜测对方要表达的真正意思
    m = 0
    key = ""
    for k in words.keys():
        # 删除多余的空白字符串
        data = ' '.join(data.split())
        # 与某个键接近就直接返回
        if len(commonprefix([k, data])) > len(k) * 0.7:
            key = k
            break
        length = len(set(data.split()) & set(k.split()))
        if length > m:
            m = length
            key = k
    s.sendto(words.get(key, 'sorry').encode(),addr)

s.close()

client端写法

import socket

# 服务端主机ip地址和端口号
HOST = '127.0.0.1'
PORT = 8085

# AF_INET = ipv4 , SOCK_DGRAM = UDP链接
s = socket.socket(socket.AF_INET,socket.SOCK_DGRAM)
while True:
    c = input('Input the content you want to send:')
    s.sendto(c.encode(),(HOST,PORT))
    # 从服务端接收数据
    data = s.recv(1024)
    data = data.decode()
    print('Received:',data)
    if c.lower() == 'bye':
        break
# 关闭连接

s.close()

==================================================================

用多线程编写 server端

import socket
import threading


PORT = 8006
HOST = ''


def server(conn , addr):
    # threading.active_count() - 1是因为主线陈也在运行
    print('总共连接数数量:',threading.active_count()-1)
    print('连接的客户机来自于:',addr)
    conn.sendall('欢迎访问本服务器'.encode())
    conn.close()

if __name__ == '__main__':
    # 链接ipv4 , 传输tcp协议
    s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    # 绑定ip和地址
    s.bind((HOST, PORT))
    # 允许连接数为5个
    s.listen(5)

    while True:
        print('等待客户机连接.......')
        conn ,addr = s.accept()
        t =threading.Thread(target=server,args=(conn , addr,))
        t.start()

client端

from socket import *

HOST = '0.0.0.0'
PORT = 8006
ADDR = (HOST, PORT)
# 创建socket对象
s = socket(AF_INET, SOCK_STREAM)
# 获取服务器连接的信息 (是否成功)
s.connect(ADDR)
data = s.recv(1024).decode()
print("服务器返回的信息:",data)
s.close()
  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值