python学习1:socket模块(TCP/IP网络编程)

本文只关心python的网络编程,并重点学习TCP/IP单元。

一、简单了解下:

1、什么是TCP/IP、UDP?

TCP/IP(Transmission Control Protocol/Internet Protocol)即传输控制协议/网间协议,是一个工业标准的协议集,它是为广域网(WANs)设计的。
         UDP(User Data Protocol,用户数据报协议)是与TCP相对应的协议。它是属于TCP/IP协议族中的一种。
        这里有一张图,表明了这些协议的关系。

TCP/IP协议族包括运输层(传输层)、网络层、(数据)链路层。现在你知道TCP/IP与UDP的关系了吧。

2、Socket在哪里呢?
       在上图中,我们没有看到Socket的影子,那么它到底在哪里呢?还是用图来说话,一目了然。

原来Socket在这里。

3、Socket是什么呢?
       Socket是应用层与TCP/IP协议族通信的中间软件抽象层,它是一组接口。在设计模式中,Socket其实就是一个门面模式,它把复杂的TCP/IP协议族隐藏在Socket接口后面,对用户来说,一组简单的接口就是全部,让Socket去组织数据,以符合指定的协议。

4、怎样使用socket?

       前人已经给我们做了好多的事了,网络间的通信也就简单了许多,但毕竟还是有挺多工作要做的。以前听到Socket编程,觉得它是比较高深的编程知识,但是只要弄清Socket编程的工作原理,神秘的面纱也就揭开了。
       一个生活中的场景。你要打电话给一个朋友,先拨号,朋友听到电话铃声后提起电话,这时你和你的朋友就建立起了连接,就可以讲话了。等交流结束,挂断电话结束此次交谈。    生活中的场景就解释了这工作原理,也许TCP/IP协议族就是诞生于生活中,这也不一定。

先从服务器端说起。服务器端先初始化Socket,然后与端口绑定(bind),对端口进行监听(listen),调用accept阻塞,等待客户端连接。在这时如果有个客户端初始化一个Socket,然后连接服务器(connect),如果连接成功,这时客户端与服务器端的连接就建立了。客户端发送数据请求,服务器端接收请求并处理请求,然后把回应数据发送给客户端,客户端读取数据,最后关闭连接,一次交互结束。

二、socket模块函数

由于socket模块中的属性太多,可直接使用import socket ,这样能大幅缩减代码。

1、socket(family,type)

创建套接字。

套接字是计算机网络数据结构。网络化的应用程序在开始任何通讯之前都必须创建套接字。可以比作电话的插口一样,没有它就完全没办法通信。

创建TCP/IP套接字:

1 tcpsock = socket(AF_INET , SOCK_STREAM)

创建UDP/IP套接字:

1 udpsock = socket(AF_INET , SOCK_DGRAM)

AF:地址家族的缩写

SOCK_STREAM:面向连接套接字,即在通信之前一定要简历一条连接(就像跟朋友打电话)。面向连接的通信方式提供了顺序的、可靠的、不会重复的数据传输,而且也不会被加上数据边界。发送信息时,信息能被拆分成多份,没分都会到达正确的目的地,然后被重新按顺序拼装起来,传给正在等待的应用程序。

SOCK_DGRAM:无连接套接字,即无需建立连接就可以进行通讯。但此时,数据到达是顺序、可靠性及不重复性就无法保证了,数据报会保留数据边界。数据是整个发送的。使用数据报来传输数据就像快递包裹一样,不一定会按发送顺序到达,而且还有可能根本到达不了。

2、套接字对象(内建)方法

函数 描述
服务器端套接字函数
s.bind()
绑定地址(主机名,端口号)到套接字

合法端口号范围为0~65535。其中小于1024的为系统保留端口,其余的均可用

s.listen() 开始TCP监听。参数表示最多允许多少个连接同时连进来,而后边的连接就会被拒绝掉
s.accept() (阻塞式)接受连接并返回(conn,address),conn是新的套接字对象,可以用来通过连接发送和接收数据,address是另一个连接端的套接字地址
客户端套接字函数
s.connect() 连接到address处的远程套接字。有错误时出现socket.error
s.connect_ex() connect()的扩展版本,出错时返回出错码,而不是抛出异常。成功返回0
公共用途的套接字函数
s.recv(bufsize [,flags]) 接收TCP数据。bufsize指定要接收的最大数据量。flags提供有关消息的其他信息,通常忽略
s.send() 发送TCP数据
s.sendall() 完整发送TCP数据
s.recvfrom(bufsize [,flags]) 接收UDP数据。返回(data,address),data是接收数据字符串,address是发送数据的套接字地址
s.sendto(string [,flags],address) 发送UDP数据。address形式是元组,指定远程地址
s.fileno()  返回套接字的文件描述符
 s.makefile(mode[,bufsize])  创建与套接字关联的文件对象。mode中‘r‘表示读取,‘w‘表示写入,‘a‘表示添加,‘+‘表示读写,‘b‘表示二进制访问。
   

3、异常

error:该异常表示与套接字或者地址有关的错误。它返回一个(errno,mesg)对以及底层系统调用返回的错误。继承自IOError。

herror:表示与地址有关的错误。返回一个包含错误编号的错误消息的元祖(herrno,hmesg)。继承自error。

4、创建TCP连接实例代码

客户端

 1 import socket
 2
 3 HOST = ‘192.168.1.100‘                          #服务器IP
 4 PORT = 12345                                     #端口号
 5 BUFSIZ = 1024
 6 ADDR = (HOST,PORT)
 7
 8 tcpCliSock = socket(AF_INET,SOCK_STREAM)        #创建TCP/IP套接字
 9 tcpCliSock.connect(ADDR)                        #尝试连接服务器
10
11 while True:
12     data = input(‘> ‘)
13     if not data:
14         break
15     tcpCliSock.send(data)              #发送TCP数据
16     data = tcpCliSock.recv(BUFSIZ)     #接收TCP数据
17     if not data:
18         break
19     print(data)
20
21 tcpCliSock.close

服务器

 1 import socket
 2 import time
 3
 4 HOST = ‘192.168.1.100‘
 5 PORT = 12345
 6 BUFSIZE = 1024
 7 ADDR = (HOST,PORT)
 8
 9 tcpSerSock = socket(AF_INET,SOCK_STREAM)
10 tcpSerSock.bind(ADDR)
11 tcpSerSock.linsten(5)
12
13 while True:
14     print(‘waiting for connection... ‘)
15     tcpCliSock,addr = tcpSerSock.accept()
16     print(‘...connected from : ‘,addr)
17
18     while True:
19         data = tcpCliSock.recv(BUFSIZE)
20         if not data:
21             break
22         tcpSerSock.send((‘ [%s] %s‘ % (ctime(),data)))
23
24         tcpCliSock.close()
25 tcpSerSock.close()

代码实现:

当有连接时,进入对话循环,等待客户端发送数据。如果消息为空,表示客户端已经退出,再等待下一个客户端连接。得到客户端消息后,在消息前叫一个时间戳然后返回。

要先开服务器,后开客户端。

5、创建UDP连接实例代码

客户端

 1 import socket
 2
 3 HOST = ‘192.168.1.100‘                          #服务器IP
 4 PORT = 12345                                     #端口号
 5 BUFSIZ = 1024
 6 ADDR = (HOST,PORT)
 7 udpCliSock = socket(AF_INET,SOCK_DGRAM)
 8
 9 while True:
10     data = input(‘> ‘)
11     if not data:
12         break
13     udpCliSock.sendto(data,ADDR)              #发送UDP数据
14     data,ADDR = udpCliSock.recvfrom(BUFSIZ)     #接收UDP数据
15     if not data:
16         break
17     print(data)
18     udpCliSock.close()
19 udpCliSock.close

服务器

 1 import socket
 2 import time
 3
 4 HOST = ‘192.168.1.100‘                          #服务器IP
 5 PORT = 12345                                     #端口号
 6 BUFSIZ = 1024
 7 ADDR = (HOST,PORT)
 8
 9 udpSerSock = socket(AF_INET,SOCK_DGRAM)
10 udpSerSock.bind(ADDR)
11
12 while True:
13     print(‘waiting for message... ‘)
14     data,addr = udpSerSock.recvfrom(BUFSIZ)
15     udpSerSock.sendto(‘[%s] %s‘ % (ctime(,data),addr))
16     print(‘ ...received from and returned to:‘,addr)
17 udpCliSock.close

UDP和TCP服务器的一个重要区别就是,由于数据报套接字是无连接的,所以无法把客户端连接交给另外的套接字进行后续的通讯。这些服务器知识接受消息,需要的话,给客户端返回一个结果就可以了。

服务器输出客户端信息的原因是,服务器可能会得到并回复多个客户端消息,这时,输出就可以了解系哦啊系来自那里。对于TCP服务器来说,由于客户端会创建一个连接,我们自然就知道消息来自那里了。

时间: 2024-08-18 14:24:52

python学习1:socket模块(TCP/IP网络编程)的相关文章

浅谈TCP/IP网络编程中socket的行为

我认为,想要熟练掌握Linux下的TCP/IP网络编程,至少有三个层面的知识需要熟悉: . TCP/IP协议(如连接的建立和终止.重传和确认.滑动窗口和拥塞控制等等) . Socket I/O系统调用(重点如read/write),这是TCP/IP协议在应用层表现出来的行为. . 编写Performant, Scalable的服务器程序.包括多线程.IO Multiplexing.非阻塞.异步等各种技术. 关于TCP/IP协议,建议参考Richard Stevens的<TCP/IP Illust

TCP/IP 网络编程 (抄书笔记 1) -- TCP

TCP/IP 网络编程 (抄书笔记 1) – TCP TCP/IP 网络编程 (抄书笔记 1) – TCP Table of Contents server client 更好的 client 端实现 来源: <TCP/IP 网络编程> 抄书: 通信的双方都各自 拥有 输入缓存和输出缓存 socket 的 write 函数并不是立即传输数据, 而是写到输出缓存区, 到达另一端的输入缓存区 socket 的 read 函数调用的瞬间, 就从输入缓存区中读取数据 TCP 协议中的滑动窗口会保证 数

《TCP/IP网络编程》

<TCP/IP网络编程> 基本信息 作者: (韩)尹圣雨 译者: 金国哲 丛书名: 图灵程序设计丛书 出版社:人民邮电出版社 ISBN:9787115358851 上架时间:2014-6-19 出版日期:2014 年6月 开本:16开 页码:1 版次:1-1 所属分类:计算机 > 计算机网络 > 网络协议 > TCP/IP 更多关于>>><TCP/IP网络编程> 编辑推荐 为初学者准备的网络编程 本书涵盖操作系统.系统编程.TCP/IP协议等多种

TCP/IP 网络编程 (抄书笔记 2) -- UDP

TCP/IP 网络编程 (抄书笔记 2) – UDP TCP/IP 网络编程 (抄书笔记 2) – UDP Table of Contents server client connect 来源: <TCP/IP 网络编程> 抄书: TCP 协议若要向 10 个客户端提供服务, 除了需要 listen 套接字外, 还需要 10 个服务器端套接字 (accept), 但是在 UDP 中, 不管是服务器端还是客户端都只需要 1 个套接字 udp 的 client 不需要 bind, 调用 sendt

TCP/IP 网络编程 (抄书笔记 3) -- 僵尸进程和多任务并发服务器

TCP/IP 网络编程 (抄书笔记 3) – 僵尸进程和多任务并发服务器 TCP/IP 网络编程 (抄书笔记 3) – 僵尸进程和多任务并发服务器 Table of Contents 僵尸进程的产生 避免僵尸进程 信号 多任务的并发服务器 僵尸进程的产生 子进程先退出, 父进程没有退出 ==> 僵尸进程 父进程先退出, 子进程没有退出 ==> 子进程被 0 号进程回收, 不会产生僵尸进程 pid_t pid = fork(); if (pid == 0) { // child printf(&

TCP/IP网络编程系列之三

TCP/IP网络编程系列之三-地址族与数据序列 分配给套接字的IP地址和端口 IP是Internet Protocol (网络协议)的简写,是为首发网络数据而分配给计算机的值.端口号并非赋予计算机值,而是为了区分程序中创建的套接字而分配给套接字的序号. 网络地址 网络地址分为IPV4和IPV6,分别你别为4个字节地址簇和6个字节地址簇.IPV4标准的4个字节的地址分为网络地址和主机地址,且分为A.B.C.D.E 等类型.一般很少用到E类型.如下图所示:net-id指网络ID,host-id指主机

TCP/IP网络编程系列之二

套接字类型与协议设置 我们先了解一下创建套接字的那个函数 int socket(int domain,int type,int protocol);成功时返回文件描述符,失败时返回-1.其中,domain是套接字使用中的协议族(Protocol Family)信息.type套接字类型里面的数据传输类型信息.protocol计算机通信中使用的协议信息. 协议族(Protocol Family) 协议族类型有: PE_INET IPV4 PE_INET6 IPV6 PF_LOCAL 本地通信的UNI

TCP/IP网络编程系列之一

概述 网络编程实际上就是编写程序使两台联网的计算机相互的交换数据.操作系统会提供名为“ 套接字 ”的部件.套接字是网络数据传输的软件设备,即使对网络数据传输原理不太熟悉也无关紧要.我们也能通过套接字完成数据传输,因此网络编程又叫套接字编程. 过程  我们可以把套接字理解为我们平时的电话机,我们先看一下套接字的创建过程: 首先你如果要和别人沟通肯定要安装好电话机才可以,所以对应套接字的是调用socket函数时进行对话. #include<sys/socket.h> int socket(int

TCP/IP网络编程系列之四(初级)

TCP/IP网络编程系列之四-基于TCP的服务端/客户端 理解TCP和UDP 根据数据传输方式的不同,基于网络协议的套接字一般分为TCP和UDP套接字.因为TCP套接字是面向连接的,因此又称为基于流的套接字.在了解TCP之前,先了解一下TCP所属的TCP/IP协议栈. 如图所示,TCP/IP协议栈共分为4层,可以理解成数据收发分成了4个层次化过程. 链路层 它是物理链接领域标准化结果,也是最基本的领域,专门定义LAN.WAN.MAN等网络标准.若两台计算机通过网络进行数据交换,链路层就负责整个物

TCP/IP网络编程系列之二(初级)

套接字类型与协议设置 我们先了解一下创建套接字的那个函数 int socket(int domain,int type,int protocol);成功时返回文件描述符,失败时返回-1.其中,domain是套接字使用中的协议族(Protocol Family)信息.type套接字类型里面的数据传输类型信息.protocol计算机通信中使用的协议信息. 协议族(Protocol Family) 协议族类型有: PE_INET IPV4 PE_INET6 IPV6 PF_LOCAL 本地通信的UNI