在网络编程中的一个基本组件就是套接字(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)讲解的更多相关文章

  1. Socket网络编程(TCP/IP/端口/类)和实例

    Socket网络编程(TCP/IP/端口/类)和实例 原文:C# Socket网络编程精华篇 转自:微冷的雨 我们在讲解Socket编程前,先看几个和Socket编程紧密相关的概念: TCP/IP层次 ...

  2. Socket网络编程TCP、UDP演示样例

    Socket网络编程: 1) OSI(了解): 国际标准化组织ISO(International Orgnization for Standardization)指定了网络通信的模型:开放系统互联(O ...

  3. Socket网络编程-TCP编程

    Socket网络编程-TCP编程 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.socket介绍 1>.TCP/IP协议 2>.跨网络的主机间通讯 在建立通信连接的 ...

  4. 网络编程TCP/IP详解

    网络编程TCP/IP详解 1. 网络通信 中继器:信号放大器 集线器(hub):是中继器的一种形式,区别在于集线器能够提供多端口服务,多口中继器,每个数据包的发送都是以广播的形式进行的,容易阻塞网络. ...

  5. Python之路【第七篇】python基础 之socket网络编程

    本篇文章大部分借鉴 http://www.cnblogs.com/nulige/p/6235531.html python socket  网络编程 一.服务端和客户端 BS架构 (腾讯通软件:ser ...

  6. Python学习之==>Socket网络编程

    一.计算机网络 多台独立的计算机通过网络通信设备连接起来的网络.实现资源共享和数据传递.在同一台电脑上可以将D盘上的一个文件传到C盘,但如果想从一台电脑传一个文件到另外一台电脑上就要通过计算机网络 二 ...

  7. python 网络编程 TCP/IP socket UDP

    TCP/IP简介 虽然大家现在对互联网很熟悉,但是计算机网络的出现比互联网要早很多. 计算机为了联网,就必须规定通信协议,早期的计算机网络,都是由各厂商自己规定一套协议,IBM.Apple和Micro ...

  8. JAVA基础知识之网络编程——-TCP/IP协议,socket通信,服务器客户端通信demo

    OSI模型分层 OSI模型是指国际标准化组织(ISO)提出的开放系统互连参考模型(Open System Interconnection Reference Model,OSI/RM),它将网络分为七 ...

  9. Python基础-week07 Socket网络编程

    一 客户端/服务器架构 1.定义 又称为C/S架构,S 指的是Server(服务端软件),C指的是Client(客户端软件) 本章的中点就是教大写写一个c/s架构的软件,实现服务端软件和客户端软件基于 ...

随机推荐

  1. CATIA 使用技巧--转换出轻巧的tif格式文件

    问题描述: 我们在与客户和供应商打交道的过程中经常需要TIF格式2D图纸文件,而默认的CATIA设置保存出来TIF文件非常大,不利于保存和传送.对于该问题,我们可以通过修改CATIA的默认设置选项,将 ...

  2. linux 设置固定IP centOS6.5

    主要是要把Linux的IP固定下来,可以用另一台机器SSH连接. ping的用法: 基本语法:ping [-选项] IP地址或域名 功能描述:测试网络是否连通 常用选项:-c -c 指定发送数据包的次 ...

  3. 547 Friend Circles 朋友圈

    班上有 N 名学生.其中有些人是朋友,有些则不是.他们的友谊具有是传递性.如果已知 A 是 B 的朋友,B 是 C 的朋友,那么我们可以认为 A 也是 C 的朋友.所谓的朋友圈,是指所有朋友的集合.给 ...

  4. jQuery height() innerHeight() outerHight() width() innerWidth() outerWidth()源码解读

    在第二层each,传入的对象以height举例是这样的,{padding:innerHeight,content:height,"":outerHeight} 对它遍历调用func ...

  5. css与JS知识整理

    CSS知识 CSS选择器:基础中的核心,选择器指明了{}中“样式”作用的对象,也就是“样式”作用于网页中的哪些元素. CSS选择器类型:一共三大类. 基础选择器    属性选择器    组合选择器  ...

  6. JS中对数组元素进行增删改移

    在js中对数组元素进行增删改移,简单总结了一下方法: 方法 说明 实例 push( ); 在原来数组中的元素最后面添加元素 arr.push("再见58"); unshift( ) ...

  7. Java项目接入阿里云OSS存储

    需求背景 目前公司内部项目所支持的文件云存储方式还是公司内部项目组提供的方案,但在时间的考验之下,弊端显现,尤其是灾备切换过程中需要切换访问地址,这种操作不方便,更可能因为中间过程的失误导致资源不可用 ...

  8. leetcode134 Gas Station

    思路: https://leetcode.com/problems/gas-station/discuss/269604/Java-Greedy-thought-process 关键是要想清楚如果从加 ...

  9. 《Head First HTML与CSS》项目实践中学到的东西

    1.组织的重要性. 首先是要建立两个根文件夹,一个存上线页面的资源,一个存测试页面的资源.所有改动内容都在测试页面的文件夹中进行,在这个文件夹中进行测试.W3C语法检测后(HTML检测网站:https ...

  10. Eclipse-运行符-数据类型转换-环境变量配置

    1.能够使用Eclipse快捷键 ctrl + /   单行注释:再按一次则取消: ctrl + shift + /  多行注释:  ctrl + shift + \  取消多行注释: ctrl + ...