Python中的socket网络编程(TCP/IP,UDP)讲解
在网络编程中的一个基本组件就是套接字(socket)。套接字基本上是两个端点的程序之间的“信息通道”。程序可能分布在不同的计算机上,通过套接字互相发送信息。套接字包括两个:服务器套接字和客户机套接字。在创建一个服务器套接字后,让它等待连接。这样它就在某个网络地址处(ip地址和端口的组合)监听,直到有客户端套接字连接。连接完成后,二者就可以进行交互了。
socket套接字
一个套接字就是socket模块中socket类的一个实例。它的实例化需要3个参数:
第1个参数是地址族,默认是socket.AF_INET(指定使用IPv4协议)
第2个参数是流,默认是socket.SOCK_STREAM(指定面向流的TCP协议),或者数据报socket.SOCK_DGRAM套接字。
第3个参数是使用的协议,默认是0
import socket
# s=socket.socket(socket.AF_INET,socket.SOCK_STREAM)
# 这里我们全部使用默认值就行了
s=socket.socket()
服务器套接字使用bind方法后,再调用listen方法去监听某个特定的地址。
s.bind(('127.0.0.1',9999))#绑定地址和端口
s.listen(5)#服务器开始监听客户端连接,允许排队等待的连接数目是5,一般都设5
端口是自己设的,ip我用的是本机的ip地址,当然如果服务器程序在其他主机上,就要换成其他的ip。端口号低于1024一般都被限制使用,它们被用于标准服务,例如端口80用于web服务。
服务器套接字开始监听后,它就静静的等待客户端的连接了。这个步骤使用accept方法完成,这个方法会阻塞直到客户端的连接。该方法返回一个格式为(client,address)的元组,client是客户端套接字,address是格式为(host,port)的元组。服务器在处理完与该客户端的连接后,再次调用accept方法开始等待下个连接,通常这个过程用一个无限循环实现。
while True:
#接受一个客户端连接
sock,addr=s.accept()#addr是个元组('127.0.0.1',端口)
#接下来可以创建新线程来处理当前客户端的连接
现在我们来看客户端怎么连接服务器,客户端套接字使用connect方法连接服务器,在connect方法中使用的地址必须和服务器在bind方法中绑定的地址相同。
import socket
c=socket.socket()#创建客户端套接字
c.connect(('127.0.0.1',9999))#连接服务器
套接字有两个方法:send和recv,分别用来发送和接收数据。send方法以字符串作为参数,recv用一个最大字节数来作为参数,如果不确定,使用1024比较好。
c.send('hello,I am xxx!')
c.recv(1024)
基础内容介绍完后,我们现在来看个完整的例子,客户端连接服务器,客户端向服务器发送一组名字xxx,然后服务器回复hello,xxx!。
#服务器
import socket
import threading
#处理客户端请求
def tcplink(sock,addr):
print('Accept new connection from %s:%s...' % addr)
sock.send('welcome!')
while True:
data=sock.recv(1024)
if data=='exit' or not data:
break;
sock.send('hello %s' % data)
sock.close()
print('Connection from %s:%s closed' % addr)
s=socket.socket()
s.bind(('127.0.0.1',9999))#绑定地址和端口
s.listen(5)
print('serve is waiting connect.....')
while True:
sock,addr=s.accept()
#创建新线程来处理每个客户端连接
#target=tcplink代表新线程要运行哪个函数
#args=(sock,addr)代表向这个方法传的参数
t=threading.Thread(target=tcplink,args=(sock,addr))
#启动这个线程
t.start()
#客户端
import socket
import threading
s=socket.socket(socket.AF_INET,socket.SOCK_STREAM)
#建立连接
s.connect(('127.0.0.1',9999))
data=s.recv(1024)
print(data)
for i in ['zhangkang','jack','tom']:
s.send(i)
data=s.recv(1024)
print(data)
s.send('exit')
s.close()
TCP建立的是可靠的连接,而UDP是无连接,不可靠的。使用UDP的时候,只需要知道目标主机的ip和端口就行了,然后直接发送,能不能到达就不一定了。
和TCP类型,服务器套接字需要先实例,然后绑定地址。
#这里第二个参数选择数据报
s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
# 绑定端口:
s.bind(('127.0.0.1', 9999))
但是服务器不需要调用listen()方法,而是直接接收客户端的数据
while True:
# 接收数据:
data, addr = s.recvfrom(1024)
print('Received from %s:%s' % addr)
s.sendto('Hello, %s!' % data, addr)
recvfrom()方法返回数据和客户端的地址与端口,这样,服务器收到数据后,直接调用sendto()就可以把数据用UDP发给客户端。
客户端使用UDP时,首先仍然创建基于UDP的Socket,然后,不需要调用connect(),直接通过sendto()给服务器发数据:
s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
for data in ['zhangkang', 'jack', 'tom']:
# 发送数据:
s.sendto(data, ('127.0.0.1', 9999))
# 接收数据:
print s.recv(1024)
s.close()
从服务器接收数据仍然调用recv()方法。
简单的聊天室程序
这里我写了一个简易的类似聊天室的程序,没有使用图形界面,全部消息都显示在控制台。
#服务器
# -*- encoding: utf-8 -*-
import socket
import threading
def tcplink(sock,addr):
print('[%s:%s] is online...' % addr)
while True:
try:
data=sock.recv(1024)
except:
socket_set.remove(sock)
print('[%s:%s] is down!' % addr)
break
if data=='exit' or not data:
socket_set.remove(sock)
sock.close()
print('[%s:%s] is down!' % addr)
break
else:
list1=[]
for i in socket_set:
if i!=sock:
list1.append(i)
for i in list1:
i.send(data)
s=socket.socket(socket.AF_INET,socket.SOCK_STREAM)
socket_set=set()#用来保存每个socket对象
s.bind(('127.0.0.1',9999))#绑定地址和端口
s.listen(5)
print('serve is waiting connect.....')
while True:
#接受一个客户端连接
sock,addr=s.accept()#addr是个元组('127.0.0.1',端口)
socket_set.add(sock)#把socket对象添加到集合中
#创建新线程来处理TCP连接
t=threading.Thread(target=tcplink,args=(sock,addr))
t.start()
#客户端
# -*- encoding: utf-8 -*-
import socket
import threading
name=raw_input('input you name:')
s=socket.socket(socket.AF_INET,socket.SOCK_STREAM)
#建立连接
s.connect(('127.0.0.1',9999))
def rec_message():
while True:
try:
data=s.recv(1024)
print('\r['+data+']')
except:
break
t=threading.Thread(target=rec_message)
t.start()
while True:
st=raw_input()
if st=='exit':
s.send(st)
s.close()
break
s.send(name+":"+st)
客户端逐个下线
Python中的socket网络编程(TCP/IP,UDP)讲解的更多相关文章
- Socket网络编程(TCP/IP/端口/类)和实例
Socket网络编程(TCP/IP/端口/类)和实例 原文:C# Socket网络编程精华篇 转自:微冷的雨 我们在讲解Socket编程前,先看几个和Socket编程紧密相关的概念: TCP/IP层次 ...
- Socket网络编程TCP、UDP演示样例
Socket网络编程: 1) OSI(了解): 国际标准化组织ISO(International Orgnization for Standardization)指定了网络通信的模型:开放系统互联(O ...
- Socket网络编程-TCP编程
Socket网络编程-TCP编程 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.socket介绍 1>.TCP/IP协议 2>.跨网络的主机间通讯 在建立通信连接的 ...
- 网络编程TCP/IP详解
网络编程TCP/IP详解 1. 网络通信 中继器:信号放大器 集线器(hub):是中继器的一种形式,区别在于集线器能够提供多端口服务,多口中继器,每个数据包的发送都是以广播的形式进行的,容易阻塞网络. ...
- Python之路【第七篇】python基础 之socket网络编程
本篇文章大部分借鉴 http://www.cnblogs.com/nulige/p/6235531.html python socket 网络编程 一.服务端和客户端 BS架构 (腾讯通软件:ser ...
- Python学习之==>Socket网络编程
一.计算机网络 多台独立的计算机通过网络通信设备连接起来的网络.实现资源共享和数据传递.在同一台电脑上可以将D盘上的一个文件传到C盘,但如果想从一台电脑传一个文件到另外一台电脑上就要通过计算机网络 二 ...
- python 网络编程 TCP/IP socket UDP
TCP/IP简介 虽然大家现在对互联网很熟悉,但是计算机网络的出现比互联网要早很多. 计算机为了联网,就必须规定通信协议,早期的计算机网络,都是由各厂商自己规定一套协议,IBM.Apple和Micro ...
- JAVA基础知识之网络编程——-TCP/IP协议,socket通信,服务器客户端通信demo
OSI模型分层 OSI模型是指国际标准化组织(ISO)提出的开放系统互连参考模型(Open System Interconnection Reference Model,OSI/RM),它将网络分为七 ...
- Python基础-week07 Socket网络编程
一 客户端/服务器架构 1.定义 又称为C/S架构,S 指的是Server(服务端软件),C指的是Client(客户端软件) 本章的中点就是教大写写一个c/s架构的软件,实现服务端软件和客户端软件基于 ...
随机推荐
- Codeforces Round #542(Div. 2) A.Be Positive
链接:https://codeforces.com/contest/1130/problem/A 题意: 给n个数,找出一个非0整数d,使所有n个数除以整数d后,数组中正数的数量>= n/2. ...
- 洛谷P2505||bzoj2750 [HAOI2012]道路 && zkw线段树
https://www.luogu.org/problemnew/show/P2505 https://www.lydsy.com/JudgeOnline/problem.php?id=2750 神奇 ...
- [已读]移动web手册
冲着作者是PPK才买的,双色,180页,略贵.但是这本书的内容,我并不是很满意.4.5.6三章算是干货,尤其是第四章,值得一读.其他的内容,忽略就好了.
- 剑指 Offer
3.1 找出数组中重复的数 来源:AcWing 题目描述 给定一个长度为 n 的整数数组 nums,数组中所有的数字都在 0∼n−1 的范围内. 数组中某些数字是重复的,但不知道有几个数字重复了,也不 ...
- Unity Shader入门精要学习笔记 - 第15章 使用噪声
转载自 冯乐乐的 <Unity Shader 入门精要> 消融效果 消融效果常见于游戏中的角色死亡.地图烧毁等效果.这这些效果中,消融往往从不同的区域开始,并向看似随机的方向扩张,最后整个 ...
- 《javascript设计模式》笔记之第六章:方法的链式调用
这一章要实现的就是jQuery的那种链式调用,例子: $(this).setStyle('color', 'green').show(); 一:调用链的结构: 首先我们来看一下最简单的$()函数的实现 ...
- vue使用props动态传值给子组件里的函数用,每次更新,呼叫函数
父组件 <template> <div id="app"> <div>详情内容</div> <button v-on:clic ...
- .NET Core 1.0 CentOS7 尝试(二、VSCode安装)
晚上继续摸索~~ 一.VSCode安装 下载VSCode,地址:https://code.visualstudio.com/Docs/?dv=linux64_rpm 直接双击安装或者使用rpm -i ...
- mybatis实现使用原生的sql
1.相应的xml文件中 <select id="selectByCategories" resultType="map" parameterType=&q ...
- 降低PNG图片存储大小方法、图片压缩方法
降低PNG图片存储大小方法,图片压缩方法,如何降低PNG图片存储大小?前提是分辨率和尺寸大小不变,图形的透明部分不变.请看如下办法,亲测可用. 1. 将PNG图片用PS打开. 2. 图像-模式-8位/ ...