一、socket代码实例

1.简单的socket通讯:

服务端代码实例:

import socket
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) # 创建socket对象 声明协议类型
sock.bind(("localhost", 9909)) # 绑定地址 端口 sock.listen(5) # 监听,5代表在允许有一个连接排队,更多的新连接连进来时就会被拒绝 conn, addr = sock.accept() # 接收客户端发来的连接请求 组成一个元祖 data = conn.recv(1024) # 接收消息 print(data) conn.send(data.upper()) # 发送消息 conn.close() # 关闭连接 sock.close() # 关闭socket

客户端代码实例:

import socket

client = socket.socket(socket.AF_INET, socket.SOCK_STREAM)  # 生成客户端实例

client.connect(("127.0.0.1", 9909))  # 连接地址端口

client.send("hello word".encode("utf8"))  # 发送消息给服务端

data = client.recv(1024)  # 接收消息
client.close() # 关闭客户端
print(data)

2.循环收发数据socket通讯:

服务端

import socket

sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.bind(("localhost", 9909)) sock.listen(5)
while True:
conn, addr = sock.accept() # 有加上一个死循环(连接循环)
while True:
try: # 适应于window系统
data = conn.recv(1024) # 通讯循环
if not data: break # 适用于linux系统
print(data) conn.send(data.upper())
except ConnectionResetError:
break conn.close() sock.close()

客户端

import socket

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

client.connect(("127.0.0.1", 9909))
while True:
msg = input(">>>:").strip()
if not msg:
continue
client.send(msg.encode("utf8"))
data = client.recv(1024)
print(data.decode('utf8'))
client.close()

3.多线程循环收发数据socket通讯:

服务端

import socket
import threading def handler(conn):
while True: # 通讯循环
try:
data = conn.recv(1024)
if not data:
break # 适用于linux系统
print(data) conn.send(data.upper())
except ConnectionResetError:
break
conn.close() sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
sock.bind(("localhost", 8889)) sock.listen(5)
while True:
conn, addr = sock.accept() # 连接循环
p = threading.Thread(target=handler, args=(conn,)) # 每来一个conn连接开启一个线程,交给handler去执行
p.start() sock.close()

服务端

import socket

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

client.connect(("127.0.0.1", 8889))
while True:
msg = input(">>>:").strip()
if not msg:
continue
client.send(msg.encode("utf8"))
data = client.recv(1024)
print(data.decode('utf8'))
client.close()

4.问题解决

有的同学在重启服务端时可能会遇到



这个是由于你的服务端仍然存在四次挥手的time_wait状态在占用地址(如果不懂,请深入研究1.tcp三次握手,四次挥手 2.syn洪水攻击 3.服务器高并发情况下会有大量的time_wait状态的优化方法)

解决方法1:

sock_server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock_server.setsockopt(socket.SOL_SOCKET,socket.SO_REUSEADDR,1) #一行代码搞定,写在bind之前
sock_server.bind((HOST, PORT))

解决方法2:

发现系统存在大量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 时间

5.基于UDP协议的套接字通讯

服务端

import socket

server_udp = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)

server_udp.bind(("127.0.0.1", 9900))

while True:
# 循环链接,拿到的是data数据,还有addr地址
# 区别于TCP协议
data, client_addr = server_udp.recvfrom(1024)
print(data)
# 发送消息send_to 消息内容+目标addr地址
server_udp.sendto(data.upper(), client_addr)
print(data)

客户端

from socket import *

client = socket(AF_INET, SOCK_DGRAM)

while True:
msg = input(">>>>>:") # 可以发送空消息,UDP是面向消息的协议所以不存在粘包现象
# 发送消息,消息+ addr地址
client.sendto(msg.encode("utf8"), ("127.0.0.1", 9900))
data, server_addr = client.recvfrom(1024)
print(data)
client.close()

6.TCP VS UDP区别

tcp基于链接通信

基于链接,则需要listen(backlog),指定连接池的大小

基于链接,必须先运行的服务端,然后客户端发起链接请求

对于mac系统:如果一端断开了链接,那另外一端的链接也跟着完蛋recv将不会阻塞,收到的是空(解决方法是:服务端在收消息后加上if判断,空消息就break掉通信循环)

对于windows/linux系统:如果一端断开了链接,那另外一端的链接也跟着完蛋recv将不会阻塞,收到的是空(解决方法是:服务端通信循环内加异常处理,捕捉到异常后就break掉通讯循环)

udp无链接

无链接,因而无需listen(backlog),更加没有什么连接池之说了

无链接,udp的sendinto不用管是否有一个正在运行的服务端,可以己端一个劲的发消息,只不过数据丢失

recvfrom收的数据小于sendinto发送的数据时,在mac和linux系统上数据直接丢失,在windows系统上发送的比接收的大直接报错

只有sendinto发送数据没有recvfrom收数据,数据丢失

socket通讯实例与TCP/UDP的区别的更多相关文章

  1. 在windows下用C语言写socket通讯实例

    原文:在windows下用C语言写socket通讯实例 From:Microsoft Dev Center #undef UNICODE #define WIN32_LEAN_AND_MEAN #in ...

  2. Socket小白篇-附加TCP/UDP简介

    Socket小白篇-附加TCP/UDP简介 Socket 网络通信的要素 TCP和UDP Socket的通信流程图 1.Socket 什么是Socket Socket:又称作是套接字,网络上的两个程序 ...

  3. 网络编程基础socket 重要中:TCP/UDP/七层协议

    计算机网络的发展及基础网络概念 问题:网络到底是什么?计算机之间是如何通信的? 早期 : 联机 以太网 : 局域网与交换机 广播 主机之间“一对所有”的通讯模式,网络对其中每一台主机发出的信号都进行无 ...

  4. Android 进阶12:进程通信之 Socket (顺便回顾 TCP UDP)

    不要害怕困难,这是你进步的机会! 读完本文你将了解: OSI 七层网络模型 TCPIP 四层模型 TCP 协议 TCP 的三次握手 TCP 的四次挥手 UDP 协议 Socket 简介 Socket ...

  5. 网络知识===TCP/UDP的区别

    TCP(传输控制协议,Transmission Control Protocol): 1)提供IP环境下的数据可靠传输(一台计算机发出的字节流会无差错的发往网络上的其他计算机,而且计算机A接收数据包的 ...

  6. http与tcp,udp的区别

    1.网络协议的概念 (1)在学习网络课程的时候,老师会讲iso七层模型,有应用层 表示层 会话层 传输层 网络层 数据链路层 物理层,其中http就属于应用层,tcp与udp是属于传输层,如图1.1( ...

  7. Socket通讯实例-基本Socket

    转自:http://www.cnblogs.com/mahaisong/archive/2011/07/25/2116475.html (讲的很好,很细) 参考:http://blog.sina.co ...

  8. TCP & UDP 的区别

    一.概念 ① TCP(Transmission Control Protocol 传输控制协议)是一种面向连接的.可靠的.基于字节流的传输层通信协议. “面向连接”就是在正式通信前必须要与对方建立起连 ...

  9. 【转载】Socket通讯原理以及TCP、IP三次握手机制分析

    要写网络程序就必须用Socket,这是程序员都知道的.而且,面试的时候,我们也会问对方会不会Socket编程?一般来说,很多人都会说,Socket编程基本就是listen,accept以及send,w ...

随机推荐

  1. Linux grep 命令大全

    grep: 用于模糊查找,在标准输入或者文件中 格式: grep [选项参数]...  PATTERN |FILE ... 选项参数说明: -E, --extended-regexp PATTERN ...

  2. python3 on macos with vscode

    brew install python3 python3 -m pip install pylint python3 -m pip install autopep8 python3 -m pip in ...

  3. cvFindContours函数

    cvFindContours函数: int cvFindContours( CvArr* image, CvMemStorage* storage, CvSeq** first_contour, in ...

  4. 前端读取Excel报表文件 js-xlsx

    1.http://www.cnblogs.com/imwtr/p/6001480.html (前端读取Excel报表文件) 2.https://github.com/SheetJS/js-xlsx

  5. nivicat premium连接阿里云数据库

    1.首先打开Navicat,文件>新建连接>MySQL连接,其他的如一图所示 其中: 连接名:自己取一个名字 主机名:填写mysql的地址 用户名:mysql的登录的用户名 密码:登录的密 ...

  6. Django的 CBV和FBV

    FBV CBV 回顾多重继承和Mixin 回到顶部 FBV FBV(function base views) 就是在视图里使用函数处理请求. 在之前django的学习中,我们一直使用的是这种方式,所以 ...

  7. python考试

    py4测试题 1.8<<2等于?322.通过内置函数计算5除以2的余数 divmod(5,2)3.s=[1,"h",2,"e",[1,2,3],&q ...

  8. QT中给程序加上主界面的图标

    首先在源码目录下面新建一个 myapp.rc的文件,在里面填写如下: IDI_ICON1 ICON DISCARDABLE "myappico.ico" (名字看自己的图片,注意图 ...

  9. 毕业生、程序猿转岗该如何选择Java、大数据和VR?答案在这里!

    许久不见的朋友请我吃饭,期间给我介绍他一个弟弟,说明年要毕业了,还不知道找啥工作,说有培训机构让他学VR.大数据什么的,不知道前景咋样,想咨询一下我.相信很多朋友面临毕业,都不知道该从事哪个行业,自己 ...

  10. 使用wsgiref库diy简单web架构

    1. 了解CGI和WSGI (1)CGI CGI(Common Gateway Interface)通用网关接口,即接口协议,前端向服务器发送一个URL(携带请求类型.参数.cookie等信息)请求, ...