文章详情

短信预约-IT技能 免费直播动态提醒

请输入下面的图形验证码

提交验证

短信预约提醒成功

网络编程-SOCKET开发

2023-01-31 00:36

关注

网络编程-SOCKET开发

B/S架构

       B指的是web(网页),S指的是Server(服务端软件)

C/S架构

       C指的是Client(客户端软件),S指的是Server(服务端软件)

OSI七层模型设计的目的

是成为一个所有计算机厂商都能实现的开放网络模型,来克服使用众多私有网络模型所带来的困难和低效性。

TCP/IP五层模型:

     应用层(表示层、会话层)http协议

              大概是OS操作系统,系统软件等用户层面的。

     传输层(TCP/UDP协议、端口、四层路由器、四层交换机)

              建立端口到端口的通信,有两种传输方式

              TCP协议:

                     TCP是全双工的通信方式,可靠传输,速度慢,对传递的数据的长短没有限制,只要不得到确认,就重新发送数据报,直到收到确认。

                     TCP的三次握手和四次挥手

 

 

SYN::同步标志(请求连接)

ACK:确认标志

FIN:结束标志

              UDP协议:

                     UDP无需连接,不可靠,速度快,传输内容长度有限制。

     网络层(IP协议、路由器、三层交换机)

         IP协议

                     IP v4、IP v6

                     IP地址根据网络ID的不同分为五种类型,分别为A、B、C、D、E类地址

  1. A类:1.0.0.0-126.0.0.0
  2. B类:128.0.0.0-191.255.255.255
  3. C类:192.0.0.0-223.255.255.255
  4. D:用于多点广播)
  5. E类:保留

*特殊:0.0.0.0-当前主机     255.255.255.255-当前子网的广播地址       127.0.0.1-本机地址,又称回环地址。

     数据链路层(ARP协议、MAC地址相关、网卡、交换机)

              ARP协议:地址解析协议,确定目标物理地址

              MAC地址:机器唯一标识

     物理层(网线)

       socket是应用层与TCP/IP协议族通信的中间软件抽象层,相当于一组接口。引用此接口可以实现TCP连接。

socket server端实例代码:

import socket        #导入socket接口

receive = socket.socket()
receive.bind(('127.0.0.1', 9999))    #此处的127.0.0.1为IP地址,9999为端口号
receive.listen()    #开始TCP监听
conn, addr = receive.accept()    #被动接收TCP客户端的连接,(阻塞)等待连接。
while True:
    conn.send('请输入用户名:'.encode('utf-8'))
    ret_user = conn.recv(1024).decode('utf-8')
    conn.send('请输入密码:'.encode('utf-8'))
    ret_psw = conn.recv(1024).decode('utf-8')
    if ret_user == 'zhao' and ret_psw == '123':
        conn.send('登录成功'.encode('utf-8'))
        break
    else:
        conn.send('用户名或密码输入错误'.encode('utf-8'))

conn.close()    #关闭套接字
receive.close()

 

socket client端实例代码:

import socket

receive = socket.socket()
receive.connect(('127.0.0.1', 9999))    #连接IP地址为127.0.0.1,端口为9999的主机

while True:
    print(receive.recv(1024).decode('utf-8'))
    user = input('>>>')
    receive.send(user.encode('utf-8'))
    print(receive.recv(1024).decode('utf-8'))
    psw = input('>>>')
    receive.send(psw.encode('utf-8'))
    ret = receive.recv(1024).decode('utf-8')
    if ret == '登录成功':
        print(ret)
        break
    else:
        print(ret)

receive.close()

 

公共用途的socket函数:

s.recv() 接收数据

s.send() 发送数据(send在待发送数据量大于己端缓存区剩余空间时,数据丢失,不会发完,可后面通过实例解释)

s.sendall() 发送完整的TCP数据(本质就是循环调用send,sendall在待发送数据量大于己端缓存区剩余空间时,数据不丢失,循环调用send直到发完)

s.recvfrom() 收到的内容为 内容+IP地址

s.close() 关闭套接字

s.getpeername() 连接到当前套接字的远端的地址

socket.setblocking(flag) #True or False,设置socket为非阻塞模式,以后讲io异步时会用

socket.getaddrinfo(host, port, family=0, type=0, proto=0,flags=0)返回远程主机的地址信息

socket.getfqdn() 拿到本机的主机名

socket.gethostbyname() 通过域名解析ip地址

黏包现象的解决

     黏包现象

              首先,黏包现象只出现在TCP传输中,由于某些原因经过TCP连续发送的信息在很短的时间内某个阶段粘连在一起发送,接收方接收到的是一条消息。

     造成黏包的原因

1. 在发送端由于两条消息发送的间隔时间很短,且两条消息本身也很短,在发送之前被合成了一条消息。

2. 在接收端由于接收不及时导致两条先后到达的信息在接收端黏在了一起。

黏包的本质

              信息与信息之间没有边界,且无法解决,因为TCP协议是流式传输。

解决黏包问题

              struct模块:

                     把任意长度的数字变成固定的4个字节。

l  简单形式(先发送数据长度,再发送数据)

l  相对规范并复杂的形式(把所有想发送的数据信息放在字典里,发送字典长度,发送字典,发送数据)

struct模块使用示例:

    发送:
    import struct
    ret=struct.pack(‘i’,10028)    #这里的’i’代表将int型10028打包
    sk.send(ret)
    接收:
    num=sk.recv(4)
    num=struct.unpack(‘I’,ret)[0]    #这里的’i’代表将ret中的内容解压为int型,必须加[0],因为它传过来的是元组。
    msg=conn.recv(num).decode(‘utf-8’)

 

socket.SOCK_DGRAM #UDP传输

实例:

server端:

import socket

while True:
    receive = socket.socket(type=socket.SOCK_DGRAM)
    receive.bind(('0.0.0.0', 9999))
    while True:
        msg, addr = receive.recvfrom(1024)
        ret = msg.decode('utf-8')
        if ret.upper() == 'Q':
            receive.sendto(bytes('您已断开连接!'.encode('utf-8')), addr)
            print('对方已与您断开连接!')
            break
        elif ret == '您已断开连接!':
            print(ret)
            break
        else:
            print(ret, addr)
        s = input('>>>').encode('utf-8')
        receive.sendto(bytes(s), addr)
receive.close()

 

client端:

import socket

receive = socket.socket(type=socket.SOCK_DGRAM)
while True:
    addr = input('输入要连接的ip地址:')
    addr_port = int(input('输入端口号:'))
    receive.connect((addr, addr_port))
    while True:
        n = input('>>>').encode('utf-8')
        receive.sendto(bytes(n), (addr, addr_port))
        msg = receive.recv(1024)
        ret = msg.decode('utf-8')
        if ret.upper() == 'Q':
            receive.sendto(bytes('您已断开连接!'.encode('utf-8')), (addr, addr_port))
            print('对方已与您断开连接!')
            break
        elif ret == '您已断开连接!':
            print(ret)
            break
        else:
            print(ret)
receive.close()

 

阅读原文内容投诉

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

软考中级精品资料免费领

  • 历年真题答案解析
  • 备考技巧名师总结
  • 高频考点精准押题
  • 2024年上半年信息系统项目管理师第二批次真题及答案解析(完整版)

    难度     807人已做
    查看
  • 【考后总结】2024年5月26日信息系统项目管理师第2批次考情分析

    难度     351人已做
    查看
  • 【考后总结】2024年5月25日信息系统项目管理师第1批次考情分析

    难度     314人已做
    查看
  • 2024年上半年软考高项第一、二批次真题考点汇总(完整版)

    难度     433人已做
    查看
  • 2024年上半年系统架构设计师考试综合知识真题

    难度     221人已做
    查看

相关文章

发现更多好内容

猜你喜欢

AI推送时光机
位置:首页-资讯-后端开发
咦!没有更多了?去看看其它编程学习网 内容吧
首页课程
资料下载
问答资讯