首页 > 代码库 > socket编程

socket编程

一、CS架构

server端要求:

1、力求一直提供服务

2、绑定到一个唯一的地址,让客户端找到

 

二、socket

socket就是为了完成C/S架构软件的开发,但是如果是C/S架构的软件就一定需要解决双方通信问题。

基于网络通信就需要了解复杂的网络协议 TCP/IP协议,于是socket出现了;

 

1、什么是sock?

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

所以,我们无需深入理解tcp/udp协议,socket已经为我们封装好了,我们只需要遵循socket的规定去编程,写出的程序自然就是遵循tcp/udp标准的

 

2、socket分类

(1)基于文件类型的套接字家族

套接字家族的名字:AF_UNIX

unix一切皆文件,基于文件的套接字调用的就是底层的文件系统来取数据,两个套接字进程运行在同一机器,可以通过访问同一个文件系统间接完成通信(Linux操作系统)

 

(2)基于网络类型的套接字家族   AF_INET

(还有AF_INET6被用于ipv6,还有一些其他的地址家族,不过,他们要么是只用于某个平台,要么就是已经被废弃,或者是很少被使用,或者是根本没有实现,所有地址家族中,AF_INET是使用最广泛的一个,python支持很多种地址家族,但是由于我们只关心网络编程,所以大部分时候我么只使用AF_INET)(ssh,nginx,mysql)

 

3、soket套接字的工作流程

技术分享

服务端:得到Socket对象,然后与端口绑定(bind),对端口进行监听(listen),调用accept阻塞,等待客户端连接。

客户端:客户端初始化一个Socket,然后连接服务器(connect),如果连接成功,这时客户端与服务器端的连接就建立了。

C/S交换阶段:客户端发送数据请求,服务器端接收请求并处理请求,然后把回应数据发送给客户端,客户端读取数据,最后关闭连接,一次交互结束

服务端套接字函数
s.bind() 绑定(主机,端口号)到套接字
s.listen() 开始TCP监听
s.accept() 被动接受TCP客户的连接,(阻塞式)等待连接的到来

客户端套接字函数
s.connect() 主动初始化TCP服务器连接
s.connect_ex() connect()函数的扩展版本,出错时返回出错码,而不是抛出异常

 

4、基于TCP协议的套接字

 

(1)实现一个简单的套接字

import socket
phon=socket.socket(socket.AF_INET,socket.SOCK_STREAM) #创建一个基于网络的(socket.AF_INET)tcp协议传输的sock(socket.SOCK_STREAM)
phon.bind(("127.0.0.1",8090)) #把创建好的套接字,绑定在 唯一的IP和端口上。
phon.listen(80)            #开始监听
conn,addr=phon.accept()   #等待客户端通过TCP三次握手发起 连接  (把某个连接,和连接的对象分解赋值给 conn,和addr)
data=http://www.mamicode.com/conn.recv(1024)      #接收 连接进来的某一个客户端,发送过来的消息
print("接受到来自客户端发来的消息",data)
conn.send(data.upper())    #发送接受的消息 给某一个客户端

执行结果

服务端:

技术分享

 

客户端:

技术分享

 

 

 

 

(2)循环通信的套接字

虽然上述已经实现了一个简单的套接字,但服务端的 socket 只能接受一次客户端的连接,所以可以利用while..Ture构建一个通信循环

服务端:

import socket
phon=socket.socket(socket.AF_INET,socket.SOCK_STREAM) #创建一个基于网络的(socket.AF_INET)tcp协议传输的sock(socket.SOCK_STREAM
phon.bind(("127.0.0.1",8090)) #把创建好的套接字,绑定在 唯一的IP和端口上。
phon.listen(80)                 #开始监听
conn,addr=phon.accept()   #等待客户端通过TCP三次握手发起 连接  (把某个连接,和连接的对象分解赋值给 conn,和addr)
while True:              #循环通信----------------------------------------------------------------------->
    data=http://www.mamicode.com/conn.recv(1024)      #接收 连接进来的某一个客户端,发送过来的消息
    print("接受到来自客户端发来的消息",data)
    conn.send(data.upper())    #发送接受的消息 给某一个客户端
conn.close()
phon.close()

客户端:

import socket
phon=socket.socket(socket.AF_INET,socket.SOCK_STREAM)
phon.connect((127.0.0.1,8090))     #客户端的phon.connect正好对于服务端的phon1.accept()
while True: #循环通信----------------------------------------------------------------------------------->>
    mes=input(---->: .strip())
    if not mes:
        continue
    res=phon.send(mes.encode(utf-8))  #发消息
    data=http://www.mamicode.com/phon.recv(1024)             #收消息
    print(data.decode(gbk))

phon.close()

 

 

 

tcp服务端

import socket
import subprocess
iphon=socket.socket(socket.AF_INET,socket.SOCK_STREAM) #(建立一个socket对象)
iphon.bind((127.0.0.1,8080))  #绑定到 IP+端口上 成为唯一的socket
iphon.listen(5)                   #设置连接池的个数
print(starting........)
while True:  #连接循环
    conn,addr=iphon.accept()  #等待电话连接
    print(电话线路是,conn)
    print(客户手机号:,addr)
    while True: #通信循环 发送和接收
        try:
            data=conn.recv(1024) #接受消息 最大从内存里接受1024MB数据
            print(客户端发来的消息是%s%data)
            data=data.decode(utf-8) #从客户端发来的数据是经过编码的字节数据 所以需要解码 成Unicode
            res=subprocess.Popen( data, shell=True, stdout=subprocess.PIPE)  #解码后传进subprocess.Popen去cmd执行
            data1 = res.stdout.read().decode(gbk)      #cmd是gbk编码所以需要gbk解码
            print(data1)                                  #打印解码后的结果
            data1=data1.encode(gbk)                   #编码
            conn.send(data1)  #发送消息                  #编码后再传输给客户端
        except Exception:
            break
    conn.close()
iphon.close()
#

 

TCP客户端

import socket
phon=socket.socket(socket.AF_INET,socket.SOCK_STREAM)
phon.connect((127.0.0.1,8080))     #客户端的phon.connect正好对于服务端的phon1.accept()
while True: #循环通信
    mes=input(---->: .strip())
    if not mes:
        continue
    res=phon.send(mes.encode(utf-8))  #发消息
    data=http://www.mamicode.com/phon.recv(1024)             #收消息
    print(data.decode(gbk))


phon.close()

 

socket编程