首页 > 代码库 > python学习1:socket模块(TCP/IP网络编程)

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

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

一、简单了解下:

1、什么是TCP/IPUDP

         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 = http://www.mamicode.com/input(> )13     if not data:14         break15     tcpCliSock.send(data)              #发送TCP数据16     data = http://www.mamicode.com/tcpCliSock.recv(BUFSIZ)     #接收TCP数据17     if not data:18         break19     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 =http://www.mamicode.com/ tcpCliSock.recv(BUFSIZE)20         if not data:21             break22         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 = http://www.mamicode.com/input(> )11     if not data:12         break13     udpCliSock.sendto(data,ADDR)              #发送UDP数据14     data,ADDR = udpCliSock.recvfrom(BUFSIZ)     #接收UDP数据15     if not data:16         break17     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     printwaiting 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服务器来说,由于客户端会创建一个连接,我们自然就知道消息来自那里了。

 

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