Socket是应用层与TCP/IP左券族通信的中等软件抽象层,笔者在那间只是简短的印证一下

socket 互联网编制程序即c/s架构

一.说明

对于TCP/udp的注脚已经重重了,作者在那只是简短的证实一下

1:硬件c/s架构(打印机)

二.套接字scoket

 套接字是一种具备从前所说的“通讯端点”概念的总计网络数据结构。特出

于电话插口,没它不能通讯,那几个比喻非常形象。
        套接字源点于20世纪70年间加州Berkeley分校版本的Unix,即BSD Unix

。又叫做“伯克利套接字”或“BSD套接字”。最早套接字被设计用在一样台

长机上五个应用程序之间的简报,那被叫作进度间通信或IPC。
        套接字分三种:基于文件型和基于互连网的
        第一个套接字家族为AF_UNIX,表示“地址家族:UNIX”。包涵

Python在内的绝大许多风靡平台上都接纳术语“地址家族”及其缩写AF。由于两

个经过都运作在平等台机器上,何况那一个套接字是依赖文件的,所以它们的底

层组织是由文件系统来援助的。能够驾驭为同一台Computer上,文件系统确实是不

同的经过都能举办拜见的。
        第二个套接字家族为AF_INET,表示”地址家族:Internet“。还大概有

一种地址家族AF_INET6被用来网际公约IPv6寻址。Python 2.5中投入了一种

Linux套接字的扶持:AF_NETLINK(无连接)套接字家族,让客商代码与基础

代码之间的IPC能够运用标准BSD套接字接口,这种艺术越来越精致和平安。
        Python只支持AF_UNIX、AF_NETLINK和AF_INET家族。网络编制程序关心

AF_INET。
        若是把套接字比作电话的查阅——即通讯的最尾部结构,那主机与端

口就一定于区号和电话号码的一对组合。多少个因特网地址由互连网通讯务必的主

机与端口组成。
        而且另一端必须要有人接听才行,不然会唤醒”对不起,您拨打大巴电

话是空号,请查询后再拨“。一样你也说不定会蒙受如”不能三番两次该服务器、服

务器无法响应“等。合法的端口范围是0~65535,在这之中型袖珍于1024端口号为系统

保留端口。

2:软件c/s架构——b/s架构(web服务)

三.面向连接与无连接

 面向连接:通讯以前一定要创设一条连接,这种通讯格局也被成为”虚电路

“或”流套接字“。面向连接的通讯情势提供了逐个的、可信地、不会再也的

数据传输,并且也不会被增进数量边界。那表示,每发送一份音信,或许会

被拆分成多份,每份都会非常少不菲地精确到达指标地,然后重新按顺序拼装起

来,传给正等待的应用程序。
公海赌船网址,        实现这种连接的要害商讨正是传输调控契约TCP。要开创TCP套接字就

得创立时内定套接字类型为SOCK_STREAM。TCP套接字那么些项目表示它作为流套

接字的性状。由于那些套接字使用网际公约IP来搜寻网络中的主机,所以这样

多变的整整系统,通常会由那五个协议(TCP和IP)组合描述,即TCP/IP。
        无连接:不须求创建连接就足以通信。但这时,数据到达的逐个、可相信

性及不重复性就不能保全了。数据报会保留数据边界,那就表示数据是全体发

送的,不会像面向连接的协商先拆分成小块。它就一定于邮政服务一样,邮件

和打包不料定遵照发送顺序达到,有的依然或许一直达到不到。并且网络中的

报文只怕会重复发送。
        那么那样多劣点,为何还要采用它呢?由于面向连接套接字要提供

一些担保,供给维护虚电路连接,那都以生死攸关的额外担负。数据报没有这么些负

担,全数它会更”低价“,常常能提供越来越好的个性,更适合有些地方,如当场

直播要求的实时数据讲究快等。
        实现这种连接的主要性钻探是顾客数量报合同UDP。要开创UDP套接字就

得创建时内定套接字类型为SOCK_DGRAM。这些名字来自datagram(数据报),

这个套接字使用网际合同来研究互连网主机,整个体系叫UDP/IP。

Socket是应用层与TCP/IP协议族通讯的中级软件抽象层,它是一组接口。在设计方式中,Socket其实便是贰个伪装形式,它把复杂的TCP/IP合同族隐蔽在Socket接口后边,让Socket去组织数据,以相符钦点的会谈。

四.socket()模块函数

  应用socket模块的socket()函数来创设套接字。语法如下:
            socket(socket_family, socket_type, protocol=0)
        其中socket_family不是AF_VNIX就是AF_INET,socket_type可以是

SOCK_STREAM或者SOCK_DGRAM,protocol日常不填,暗许值是0。
        成立一个TCP/IP套接字的语法如下:
             tcpSock = socket.socket(socket.AF_INET,

socket.SOCK_STREAM)
        同样创制三个UDP/IP套接字的语法如下:
             udpSock = socket.socket(socket.AF_INET,

socket.SOCK_DGRAM)
        由于socket模块中有太多属性,所以选择”from socket import *”语

句,把socket模块里面包车型地铁装有属性都带到命名空间中,小幅降低代码。调用如

下:
             tcpSock = socket(AF_INET, SOCK_STREAM)

 

依附文件类型的套接字家族

五.套接字对象

上面是最常用的套接字对象方法:
       服务器端套接字函数

socket类型

描述

s.bind()

绑定地址(主机号 端口号对)到套接字

s.listen()

开始TCP监听

s.accept()

被动接受TCP客户端连接,(阻塞式)等待连续的到来

       客商端套接字函数

socket类型

描述

s.connect()

主动初始化TCP服务器连接

s.connect_ex()

connect()函数扩展版本,出错时返回出错码而不是跑出异常

       公物用途的套接字函数

socket类型

描述

s.recv()

接受TCP数据

s.send()

发送TCP数据

s.sendall()

完整发送TCP数据

s.recvfrom()

接受UDP数据

s.sendto()

发送UDP数据

s.getpeername()

连接到当前套接字的远端地址(TCP连接)

s.getsockname()

获取当前套接字的地址

s.getsockopt()

返回指定套接字的参数

s.setsockopt()

设置指定套接字的参数

s.close()

关闭套接字

        面向模块的套接字函数

socket类型

描述

s.setblocking()

设置套接字的阻塞与非阻塞模式

s.settimeout()

设置阻塞套接字操作的超时时间

s.gettimeout()

得到阻塞套接字操作的超时时间

        面向文件的套接字函数

 

socket类型

描述

s.fileno()

套接字的文件描述符

s.makefile()

创建一个与套接字关联的文件对象

套接字家族的名字:AF_UNIX—-基于文件

六.代码达成

 TCP服务端代码

#! /usr/bin/env python
#coding=utf-8
import socket
bind_ip = ""
bind_port = 9999

server = socket.socket(socket.AF_INET,socket.SOCK_STREAM)

server.bind((bind_ip,bind_port))

server.listen(5)
try:
        while True:
                client,add = server.accept()
                print "[*]你监听的是:%s:%d" % (add[0],add[1])
                while True:
                        data = client.recv(1024)
                        if not data:
                                break
                        print data
                        data = raw_input('> ')
                        client.send(data)
#                       print data
                else:
                        client.close()
except Exception as e:
        print e
server.close()

TCP顾客端代码

#! /usr/bin/env python
#coding=utf-8

import socket

target_host = "127.0.0.1"
target_port = 9999

#建立一个socket对象
client = socket.socket(socket.AF_INET,socket.SOCK_STREAM)

#链接客户端
client.connect((target_host,target_port))


while True:
        data = raw_input('> ')
        client.send(data)

        #发送一些数据
        #client.send("GET /HTTP/1.1\r\nHost:baidu.com\r\n\r\n")
        data = client.recv(4096)
        if not data:
                break
        print data

 

UDP服务端

# -*- coding: utf-8 -*- 
from socket import *
from time import ctime

HOST = ''                   #主机名
PORT =  21567               #端口号
BUFSIZE = 1024              #缓冲区大小1K
ADDR = (HOST,PORT)

udpSerSock = socket(AF_INET, SOCK_DGRAM)
udpSerSock.bind(ADDR)       #绑定地址到套接字

while True:                 #无限循环等待连接到来
    try:
        print 'Waiting for message ....'
        data, addr = udpSerSock.recvfrom(BUFSIZE)          #接受UDP
        print 'Get client msg is: ', data
        udpSerSock.sendto('[%s] %s' %(ctime(),data), addr) #发送UDP
        print 'Received from and returned to: ',addr

    except Exception,e:
        print 'Error: ',e
udpSerSock.close()          #关闭服务器

UDP服务端

# -*- coding: utf-8 -*- 
from socket import *

HOST = 'localhost'          #主机名
PORT =  21567               #端口号 与服务器一致
BUFSIZE = 1024              #缓冲区大小1K
ADDR = (HOST,PORT)

udpCliSock = socket(AF_INET, SOCK_DGRAM)

while True:                 #无限循环等待连接到来
    try:
        data = raw_input('>')
        if not data:
            break
        udpCliSock.sendto(data, ADDR)            #发送数据
        data,ADDR = udpCliSock.recvfrom(BUFSIZE)  #接受数据
        if not data:
            break
        print 'Server : ', data

    except Exception,e:
        print 'Error: ',e

udpCliSock.close()          #关闭客户端

 

unix一切皆文件,基于文件的套接字调用的正是底层的文件系统来取数据,三个套接字进度运转在同一机器,能够经过寻访同二个文件系统直接完结通讯

遵照网络项目标套接字家族

套接字家族的名字:AF_INET—-基于网络

(还有AF_INET6被用于ipv6,还应该有一部分另外的地方家族,可是,他们依然是只用于有些平台,要么正是曾经被遗弃,恐怕是少之甚少被应用,大概是平昔未有落实,全体地方家族中,AF_INET是行使最广大的叁个,python扶持很三种地点家族,不过由于大家只关切网络编制程序,所以大多数时候小编么只使用AF_INET)

面向连接的套接字:通讯前须求先创建贰个接二连三。—-虚构电路/流套接字

面向连接的通讯提供类别化的,可相信的喝不重复的多寡交由,而并未记录边界。完成面向连接类型的基本点探讨是传输调控合同TCP,socket使用socket.SOCK.STREAM作为套接字类型。

无连接的套接字:  通讯前无需树立连接。

在数量传输进度中并不可能担保它的顺序性,可相信性和重复性。数据报保存了笔录边界。达成无连接类型的主要性是客户数量报左券UDP,socket使用SOCK.DGRAM作为套接字类型。

面向连接套接字—模仿ssh 命令

#!/usr/bin/env python
# -*- coding: utf-8 -*-
# Created by Mona on 2017/7/10
#服务端:

import socket
import subprocess
phone_server=socket.socket(socket.AF_INET,socket.SOCK_STREAM) #买手机
phone_server.setsockopt(socket.SOL_SOCKET,socket.SO_REUSEADDR,1) #就是它,在bind前加,防止服务器断开后端口未清除
phone_server.bind(('127.0.0.1',8080)) #绑手机卡

phone_server.listen(5) #开机

print('server run...')
while True:
    conn,client_addr=phone_server.accept() #等电话
    print('客户端: ',client_addr)

    while True: #通讯循环
        try:
            cmd=conn.recv(1024) #收消息
            res=subprocess.Popen(cmd.decode('utf-8'),
                             shell=True,
                             stdout=subprocess.PIPE,
                             stderr=subprocess.PIPE)

            stdout=res.stdout.read()
            stderr=res.stderr.read()
            conn.sendall(stdout+stderr)
        except Exception:
            break

    conn.close() #挂电话

phone_server.close() #关机

#客户端:
import socket
client_phone = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
client_phone.connect(('127.0.0.1',8080))

while True:
    cmd = input('>>>>:').strip()
    if not cmd:continue
    client_phone.send(cmd.encode('utf-8'))

    sever_msg = client_phone.recv(1024)
    print(sever_msg.decode('utf-8'))

client_phone.close()

有线连接套接字——-模仿多人闲谈

#!/usr/bin/env python
# -*- coding: utf-8 -*-
# Created by Mona on 2017/7/10

#服务端
import socket
ip_port = ('127.0.0.1',8081)
udp_server = socket.socket(socket.AF_INET,socket.SOCK_DGRAM)
udp_server.bind(ip_port)

while True:
    qq_msg,addr = udp_server.recvfrom(1024)
    print('来自[%s:%s]的一条消息:\033[1;44m%s\033[0m'%(addr[0],addr[1],qq_msg.decode('utf-8')))
    back_msg = input('回复消息:').strip()
    udp_server.sendto(back_msg.encode('utf-8'),addr)

#客户端1
import socket
udp_server = socket.socket(socket.AF_INET,socket.SOCK_DGRAM)
qq_name = {'mona':('127.0.0.1',8081),'egon':('127.0.0.1',8081),'alex':('127.0.0.1',8081)}

while True:
    qq_name_client = input('请选择聊天对象:').strip()
    while True:
        msg = input('请输入消息,回车发送').strip()
        if msg == 'quit': break
        if not msg or not qq_name_client or qq_name_client not in qq_name:continue
        udp_server.sendto(msg.encode('utf-8'),qq_name[qq_name_client])
        back_msg,addr  = udp_server.recvfrom(1024)
        print('来自[%s:%s]的一条消息:\033[1;44m%s\033[0m' % (addr[0], addr[1], back_msg.decode('utf-8')))

#客户端2:
import socket

udp_server = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
qq_name = {'mona': ('127.0.0.1', 8081), 'egon': ('127.0.0.1', 8081), 'alex': ('127.0.0.1', 8081)}

while True:
    qq_name_client = input('请选择聊天对象:').strip()
    while True:
        msg = input('请输入消息,回车发送').strip()
        if msg == 'quit': break
        if not msg or not qq_name_client or qq_name_client not in qq_name: continue
        udp_server.sendto(msg.encode('utf-8'), qq_name[qq_name_client])
        back_msg, addr = udp_server.recvfrom(1024)
        print('来自[%s:%s]的一条消息:\033[1;44

 

 

 

相关文章