一、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. 【mysql 】sql删除重复记录 You can't specify target table '表名' for update in FROM clause

    用下面的语句就报语法出错: delete from tab_record where recordid not in (select  min(c.recordid) as recordid from ...

  2. 原生JS日历 + JS格式化时间格式

    公司项目中用到,以前没做过,废了好几个小时 终于做好了 先来效果图(暂时没写样式 凑合着看吧) 点击左右按钮都能改变月份 下方表格中的数据也会跟着变化 贴上代码 : html部分: <div s ...

  3. mysql注入介绍

    0. SQL注入常用的尝试语句: or 1=1--+ 'or 1=1--+ "or 1=1--+ )or 1=1--+ ')or 1=1--+ ") or 1=1--+ " ...

  4. LeetCode OJ :Unique Binary Search Trees II(唯一二叉搜索树)

    题目如下所示:返回的结果是一个Node的Vector: Given n, generate all structurally unique BST's (binary search trees) th ...

  5. 剑指offer--24.树的子结构

    时间限制:1秒 空间限制:32768K 热度指数:407165 题目描述 输入两棵二叉树A,B,判断B是不是A的子结构.(ps:我们约定空树不是任意一个树的子结构)   class Solution ...

  6. pg_test_fsync使用记录

    pg_test_fsync pg_test_fsync旨在让您合理地了解特定系统上最快的wal_sync_method,以及在发生识别的I / O问题时提供诊断信息. 但是,pg_test_fsync ...

  7. Ganymed实现基本的自动化部署API

    Ganymed SSH-2 for Java是一个纯Java实现的SHH2库,官网为http://www.ganymed.ethz.ch/ssh2/,最新的更新时间为2006年10月,在用之前,请仔细 ...

  8. Ubuntu使用PlayOnLinux笔记

    playonlinux官网:https://www.playonlinux.com/en/ 帮助文档:https://www.playonlinux.com/en/documentation.html ...

  9. Android 蓝牙 socket通信

    Android中蓝牙模块的使用 使用蓝牙API,Android应用程序能够执行以下功能: 扫描其他蓝牙设备查询本地已经配对的蓝牙适配器建立RFCOMM通道通过服务发现来连接其他设备在设备间传输数据管理 ...

  10. 【前端】JavaScript入门学习

    <button type="button" onclick="alert('hillo!')">Here</button> <sc ...