socket构造方法,构造函数中调用socket
socket的概念socket是中间软件的抽象层,其APP应用层与TCP/IP协议族进行通信,是一系列接口。在设计模式下,socket其实就是门模式,把复杂的TCP/IP协议族隐藏在socket接口后面。对于用户来说,所有的简单接口都是为了使套接字符合指定的协议而设计的,数据如下所示:
让我们从服务器开始。服务器首先初始化socket,然后绑定端口,监听端口,调用accept来阻塞,等待客户端的连接。如果客户端初始化套接字并连接到服务器,如果连接成功,客户端和服务器之间的连接将被建立。客户端发送数据请求,服务器接收并处理请求,向客户端发送响应数据,客户端读取数据,最后关闭连接,第一次交互结束。
“3358www。网络层的Sina.com/"可以唯一标识网络中的主机,传输层的“
ip地址
”可以唯一标识主机中的APP位置(进程)。这可以允许三重重组(ip地址、协议、端口)来标识网络进程,网络中的进程通信可以使用该标记与其他进程进行交互。使用TCP/IP协议的APP应用通常使用UNIX BSD socket来提供网络进程间的通信。现在大部分APP应用都使用sockets,但是现在是互联网时代,网络中的进程通信随处可见。所以说“都是插座”。
Socket起源于Unix,Unix/Linux的基本哲学之一是“所有文件”,可以在“打开-打开”-读写-关闭“关闭”模式下操作。我的理解是socket是这个模式的实现,socket是一个特殊的文件,有些socket函数就是对它的操作(I/o读/写,打开,关闭)。
socket函数socket函数对应的是打开一个普通文件的操作。常规文件打开操作返回文件描述符,但用于创建套接字(或唯一标识套接字的套接字描述符)。这个套接字描述符和文档描述符一样,也会在后续操作中使用。它用作读写操作的参数。
socket.socket([family[,type[,proto]]参数的详细信息
故障地址序列必须是AF_INET(默认)、AF_INET6、AF_UNIX、AF_CAN或AF_RDS。
(AF_UNIX域实际使用本地socket文件进行通信)类型SOCK类型是SOCK_STREAM,SOCK_DGRAM,SOCK_RAW或者其他SOCK_RAW SOCK_STREAM是基于TCP的,可以保证正确的数据传输给对方。面向连接的套接字通常用于数据传输。
SOCK_DGRAM是一个基于UDP的不安全的面向消息的套接字,常用于在互联网上发布广播信息。调用socket创建socket时,返回的socket描述符存在于协议族空间中,但没有具体的地址。要分配地址,必须调用bind(函数。否则,当调用(connect),(listen))时,将自动随机分配端口。
作为服务器,在调用socket(,bind),之后是listen),它接收这个socket,然后当客户端调用connect)时,它发送一个连接请求,服务器会接收这个请求。
TCP服务器通过调用socket(),binding()监听指定的套接字地址,依次监听。TCP客户端在依次调用socket()和connect()后,想要向TCP服务器发送连接请求。当TCP服务器收到请求时,它调用accept()函数来接收传入的请求并建立连接。然后,就可以开始网络I/O操作了,也就是和普通文件一样的读/写I/O操作。
Bind))函数为套接字指定地址族中的特定地址。
Listen))函数的第一个参数是要接收的套接字描述符,第二个参数是对应套接字可以排队的最大连接数。Socket))函数创建的socket默认是主动的,listen函数将socket改为被动的,等待客户的连接请求。
Connect))函数的第一个参数是客户端套接字描述符,第二个参数是服务器的套接字地址,第三个参数是套接字地址的长度。调用客户端的connect函数建立与TCP服务器的连接。
accept))函数的第一个参数是服务器套接字描述符,第二个参数是指向客户端协议地址的指针,第三个参数是协议地址的长度。如果accpet成功,返回值将是内核自动生成的新描述符,指示与返回客户的TCP连接。
accept函数返回连接的套接字描述符。通常情况下,一个服务器只创建一个接收套接字描述符,并且它始终存在于服务器的整个生命周期中。为内核服务器进程接受的每个客户端连接创建一个连接套接字描述符,在服务器完成对客户端的服务后关闭对应的连接套接字描述符。
read()函数负责从fd中读取内容。当读取成功时,read返回实际读取的字节数。如果返回值为0,则意味着文件的结尾已被读取。小于0表示发生了错误。如果错误是EINTR,说明读数是中断造成的,如果是ECONNREST,说明网络连接有问题。
Write()在网络程序中,我们写入socket文件描述符时有两种可能。1)1)write的返回值大于0,表示已经写入了部分或全部数据。2)返回值小于0,此时出现错误。我们必须根据错误的类型来处理它。如果错误为EINTR,则意味着在写入过程中发生了中断错误。如果EPIPE指示网络连接有问题(对方已经关闭连接)
Close()服务器和客户端建立连接后,会执行一些读写操作。当读写操作完成后,相应的socket描述符会被关闭,就像操作完打开的文件后调用fclose关闭打开的文件一样。
TCP套接字的默认行为是将套接字标记为关闭,然后立即返回到调用进程。该描述符不能再被调用进程使用,也就是说,它不能再被用作read或write的第一个参数。
注意:关闭操作只使对应的套接字描述符的引用计数为-1,只有当引用计数为0时,才会触发TCP客户端向服务器发送连接终止请求。
下面是用socket函数写的QQ聊天程序:
客户:
插入导入socket client=socket . socket(type=socket . sock _ dgram)#此处创建一个服务器socket对象Ip _ port=( 10 . 10 . 42 . 39 ,900)) #服务器地址和端口content=input(我在聊天中键入的内容:)content=content . encode( utf-8 )# encode U in UTF-8获取字节(二进制)类型对象,encode是字符串函数client.sendto(content,Ip_port)#向服务器发送消息,client . Send发送udtaddress是(ipaddr,port)形式的元组,它指定远程地址。返回值是发送的字节数。Msg,addr=client.recvfrom (1024) #接受一个消息(client.recvfrom,接收UDP数据,类似recv(),但返回值是(data,address)。其中data是包含接收数据的字符串,address是发送数据的套接字地址。)msg=msg . decode( UTF-8 )print(msg,addr) #输出代码片服务器:
这里导入socket server=socket . socket(type=socket . sock _ dgram)#创建一个服务器socket对象server.bind ((10.10.42.10 ,9000)) #监听本地端口9000(bind函数将socket绑定到地址,在python下,用tuple (host,port)的形式表示地址)而true: msg,addr=server.recvfrom (1024) #接受客户端发来的信息,1024表示msg=msg.decode(Server.close()#插入代码片段