zoukankan      html  css  js  c++  java
  • 31 socket客户端. 服务器 异常 语法

    Socket是应用层与TCP/IP协议族通信的中间软件抽象层,它是一组接口。

    基于文件类型的套接字家族

    套接字家族的名字:AF_UNIX

    unix一切皆文件,基于文件的套接字调用的就是底层的文件系统来取数据,两个套接字进程运行在同一机器,可以通过访问同一个文件系统间接完成通信

    基于网络类型的套接字家族

    套接字家族的名字:AF_INET

    服务器端先初始化Socket,然后与端口绑定(bind),对端口进行监听(listen),调用accept阻塞,等待客户端连接。在这时如果有个客户端初始化一个Socket,然后连接服务器(connect),如果连接成功,这时客户端与服务器端的连接就建立了。客户端发送数据请求,服务器端接收请求并处理请求,然后把回应数据发送给客户端,客户端读取数据,最后关闭连接,一次交互结束

    socket()模块函数用法

    import  socket
    # socket实例类
    serve=socket.socket(socket.AF_INET,socket.SOCK_STREAM)


    serve.bind(('127.0.0.1',12))
    # serve.bind('127.0.0.1',端口)
    # 127.0.0.1这叫回送地址 表示电脑本身
    # 端口 为普通整数
    # 参数为一个元组


    serve.listen()
    # 监听

    # 接收链接请求
    # 第一个是表示客户端的socket 第二个客户端的地址信息
    client,addr=serve.accept()

    serve.recv(10)
    # 接收数据 单位为字节

    serve.close()
    # 关闭数据

    socket服务端
    import socket


    # 作为服务器,ip和端口号是明确的
    # 参数1指定 AF_INET 为网络类型 , AF_UNIX 为文件类型
    # 参数2 指定SOCK_STERAM 表示TCP协议 SOCK_DGRAM 为udp协议

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

    # 默认就是网络类型 TCP协议
    # serve = socket.socket()


    server.bind(('127.0.0.1', 122))
    # 开始监听1688端口
    server.listen()


    # 接收链接请求
    # 第一个是表示客户端的socket 第二个客户端的地址信息
    client,addr=server.accept()

    data=client.recv(122)
    client.send('222222'.encode('utf-8'))

    server.close()
    # 关机
    socket客户端

    常见的异常
    服务端
    import socket


    client=socket.socket()


    # 所有系统会自动分配随机端口给客户端

    client.connect(('127.0.0.1', 122))
    # 开始通话
    # 发送数据 注意发送的内容只能是二进制 bytes
    client.send('111111111'.encode('utf-8'))

    data = client.recv(122)

    client.close()
    import socket
    sever = socket.socket()

    sever.bind(('127.0.0.1', 133))

    sever.listen()

    # accept 是一个阻塞函数 会一直等到有客户端链接过来 在继续执行
    client,addr=sever.accept()
    print('三次握手成功')

    # 收发数据 注意都是用表示客户端的socket来收发数据
    # client.send('hello'.encode('utf-8'))
    try:
    data=client.recv(100)
    print('客户端发来的数据',data)
    except:
    print('client 下线')
    client .close()
    print('完成四次挥手')


    # 休10秒
    import time
    time.sleep(10)




    sever.close()
    print('服务器关机')
    客户端
    import socket
    client=socket.socket()


    # connect本质实在进行三次握手 也是一个数据传输的过程 如果服务器没有立马响应 也会阻塞

    client.connect(('127.0.0.1',133))

    print('握手成功!')

    # 发送数据 本质上是把数据交给操作系统来进行发送 一旦数据交给了操作系统 后续的发送
    # 应用程序就无法控制了 ,send一般不会卡 当然 如果数据量很大就会阻塞
    # client.send('hello'.encode('utf-8'))
    # print('发送完成')


    # 是从操作系统缓存区读取数据 如果当前还没有任何数据 就会进入阻塞
    # 会一直等到有数据到来 再继续执行
    try:
    data=client.recv(100)
    print('客户端的数据',data)
    except:
    print('client 下线')


    # 客户端执行close 是正常关闭链接 会给服务器送空字节 用于表示要断开链接
    client.close()
    print('客户端关机')
    import socket
    server = socket.socket()

    server.bind(('127.0.0.1',11))
    server.listen()
    server.accept()

    server.close()

    异常

    # 如果已经开启了服务器 再次运行将会抛出 端口占用异常 把之前开启的服务器关掉即可

    1.可能是由于你已经启动了服务器程序,却又再次启动了服务器程序,同一个端口不能被多个进程使用导致!

    2.三次握手或四次挥手时,发生了异常导致对方程序已经结束而服务器任然处于time_wait状态导致!

    3.在高并发的场景下,由于链接的客户端太多,也会产生大量处于time_wait状态的链接


    """
    有些情况 明明已经关闭了进程 但是 还是端口占用
    可能是进程正在后台运行 可以通过端口查出进程 进行关闭
    windows下
    netstat -ano | findstr 9898
    tasklist | findstr 进程id 拿到进程名称
    taskkill /f /t /im 进程名称
    大招: 重启电脑
    """
    循环
    服务器
    import socket
    sever = socket.socket()
    # 指定服务器的端口和ip 客户端的端口系统自动分配的
    sever.bind(('127.0.0.1',36))
    sever.listen()


    while True:
    client_socket,client_addr=sever.accept()
    buffer_size=1024
    # 缓冲区  就是一个临时的容器  

    while True:
    try:
    data=client_socket.recv(1024)
    if not data:
    client_socket.close()
    break

    print(data.decode('utf-8'))
    # 解码时必须保证双方同意编码方式
    # 转为大写在发回去
    client_socket.send(data.upper())
    except ConnectionResetError as a:
    print('%s %s" % (client_addr[0],client_addr[1]),e')
    # 如果对方下线了 那服务器也应该关闭对应的客户端对象
    client_socket.close()
    break

    客户端
    import  socket

    client=socket.socket()
    client .connect(('127.0.0.1',36))


    while True:
    msg=input('输入内容...')
    if msg == 'q':
    break
    if not msg:
    continue
    client.send(msg.encode('utf-8'))
    print('发送')
    data = client.recv(1024)
    print(data.decode('utf-8'))

    client.close()

    windows正常关闭
    服务器
    import socket
    sever = socket.socket()

    sever.bind(('127.0.0.1',96))
    sever.listen()

    while True:
    client_socket,client_addr=sever.accept()
    buffer_size=1024

    while True:
    try:

    data=client_socket.recv(1024)
    if not data:
    print(data)

    break

    print('收到数据...',data.decode('utf-8'))
    # 解码时必须保证双方同意编码方式
    # 转为大写在发回去
    client_socket.send(data.upper())
    except ConnectionResetError as a:
    print('%s %s'%(client_addr[0],client_addr[1]),a)
    # 如果对方下线了 那服务器也应该关闭对应的客户端对象
    break

    client_socket.close()
    客户端

    import socket
    client=socket.socket()

    client.connect(('127.0.0.1',96))


    # 添加循环 用来重复收发数据

    while True:
    # 收发的顺序 必须和对面相反 否则卡死了
    msg= input('输入内容....q 退出')
    if msg == 'q':
    break
    if not msg:
    continue
    client.send(msg.encode('utf-8'))
    print('发送')
    data = client.recv(1024)
    print(data.decode('utf-8'))
    client.close()











  • 相关阅读:
    Ado.Net 调用存储过程用法
    C程序设计语言练习题1-22
    C程序设计语言练习题1-21
    C程序设计语言练习题1-20
    C程序设计语言练习题1-19
    C程序设计语言练习题1-18
    C程序设计语言练习题1-17
    C程序设计语言练习题1-16
    C程序设计语言练习题1-15
    C程序设计语言练习题1-14
  • 原文地址:https://www.cnblogs.com/komorebi/p/10940771.html
Copyright © 2011-2022 走看看