码迷,mamicode.com
首页 > 其他好文 > 详细

Socket接口

时间:2018-04-02 20:20:10      阅读:196      评论:0      收藏:0      [点我收藏+]

标签:重启   用户   eset   程序   允许   拨号   创建   inf   127.0.0.1   

Socket接口

Socket: Socket是应用层与TCP/IP协议族通信的中间软件抽象层,它是一组接口。在设计模式中,Socket其实就是一个门面模式,它把复杂的TCP/IP协议族隐藏在Socket接口后面,对用户来说,一组简单的接口就是全部。

1.简单的套接字通信

服务端

import socket

#1.买手机 创建一个套接字对象
phone=socket.socket(socket.AF_INET,socket.SOCK_STREAM) #基于网络通信的套接字 (TCP)
# print(phone)

#2.绑定手机卡(ip地址)
phone.bind((127.0.0.1,8080)) # 端口0-65535: 0-1024是给操作系统使用的

#3.开机
phone.listen(5) #最大挂起的链接数

#4.等电话链接
print(starting...)
conn,client_addr=phone.accept() #conn 电话线 拿到可以收发信息的管道
#accept 对应客户端的connect 三次握手

#5.收,发消息
data = conn.recv(1024) #1.单位:bytes 2. 1024代表接受1024个bytes
print(客户端的数据,data)

conn.send(data.upper())

#6.挂电话
conn.close()

#7.关机
phone.close()

客户端

import socket

#1.买手机 客户端的phone 相当于服务端的conn
phone=socket.socket(family=socket.AF_INET,type=socket.SOCK_STREAM)
# print(phone)

#2.拨号 (服务端的ip 和服务端的 端口)
phone.connect((127.0.0.1,8080)) #0-65535: 0-1024是给操作系统使用的

#3.发收消息 bytes型
phone.send(hello.encode(utf-8))
data = phone.recv(1024)
print(data)

#4.关闭
phone.close()

2.加上通信循环

服务端

import socket

phone=socket.socket(socket.AF_INET,socket.SOCK_STREAM)
phone.bind((127.0.0.1,8081))
phone.listen(5)

print(starting...)
conn,client_addr=phone.accept()
print(client_addr)

while True: #通信循环
    data = conn.recv(1024)
    print(客户端的数据,data)
    conn.send(data.upper())

conn.close()
phone.close()

客户端

import socket

phone=socket.socket(family=socket.AF_INET,type=socket.SOCK_STREAM)
phone.connect((127.0.0.1,8081)) #0-65535: 0-1024是给操作系统使用的

while True:
    msg = input(>>: ).strip()
    phone.send(msg.encode(utf-8))
    data = phone.recv(1024)
    print(data)
phone.close()

3.C与S的bug修复

技术分享图片

BUG问题:

1.端口的重复使用

问题:重启服务端时可能会遇到

技术分享图片

这个是由于你的服务端仍然存在四次挥手的time_wait状态在占用地址

windows解决方法

#服务端代码
phone=socket.socket(socket.AF_INET,socket.SOCK_STREAM)
phone.setsockopt(socket.SOL_SOCKET,socket.SO_REUSEADDR,1) #SO_REUSEADDR 可以让ip端口重用
phone.bind((127.0.0.1,8080))

linux解决方法

发现系统存在大量TIME_WAIT状态的连接,通过调整linux内核参数解决,
vi /etc/sysctl.conf

编辑文件,加入以下内容:
net.ipv4.tcp_syncookies = 1
net.ipv4.tcp_tw_reuse = 1
net.ipv4.tcp_tw_recycle = 1
net.ipv4.tcp_fin_timeout = 30
 
然后执行 /sbin/sysctl -p 让参数生效。
 
net.ipv4.tcp_syncookies = 1 表示开启SYN Cookies。当出现SYN等待队列溢出时,启用cookies来处理,可防范少量SYN攻击,默认为0,表示关闭;

net.ipv4.tcp_tw_reuse = 1 表示开启重用。允许将TIME-WAIT sockets重新用于新的TCP连接,默认为0,表示关闭;

net.ipv4.tcp_tw_recycle = 1 表示开启TCP连接中TIME-WAIT sockets的快速回收,默认为0,表示关闭。

net.ipv4.tcp_fin_timeout 修改系統默认的 TIMEOUT 时间

2.客户端关闭

服务端

import socket

phone=socket.socket(socket.AF_INET,socket.SOCK_STREAM)
phone.setsockopt(socket.SOL_SOCKET,socket.SO_REUSEADDR,1) #SO_REUSEADDR 可以让ip 端口重用
phone.bind((127.0.0.1,8080))
phone.listen(5)

print(starting...)
conn,client_addr=phone.accept()
print(client_addr)

while True: #通信循环
    try:
        data = conn.recv(1024)
        # if not data:break #适用于linux操作系统
        print(客户端的数据,data)
        conn.send(data.upper())
    except ConnectionResetError:#使用于windows操作系统
        break

conn.close()
phone.close(

客户端

客户端应用程序在发送的时候:send==空-->客户端的操作系统内存 收到为空---> 不会调用任何协议,没有发送数据给,服务端的操作系统内存

服务端应用程序在接受的时候:服务端的操作系统内存由于没有接收到数据,所以一直卡在,应用程序的recv接受过程

import socket

phone=socket.socket(family=socket.AF_INET,type=socket.SOCK_STREAM)
phone.connect((127.0.0.1,8080)) #0-65535: 0-1024是给操作系统使用的

while True:
    msg = input(>>: ).strip() # msg =‘‘
    if not msg:continue
    phone.send(msg.encode(utf-8)) #phone.send(b‘‘)
    # print(‘has send‘) #验证可以发空
    # >>:   has send
    data = phone.recv(1024)
    # print(‘has recv‘) #验证在发空的情况下 是否可以接受消息
    #>>:   has send
    print(data.decode(utf-8)) 

phone.close()

4.加上链接通信

服务端

 

客户端

Socket接口

标签:重启   用户   eset   程序   允许   拨号   创建   inf   127.0.0.1   

原文地址:https://www.cnblogs.com/Mryang123/p/8695815.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!