socket编程

 一、网络通信要素   

  A:IP地址 

    (1) 用来标识网络上一台独立的主机     

    (2) IP地址 = 网络地址 + 主机地址(网络号:用于识别主机所在的网络/网段。主机号:用于识别该网络中的主机)
      (3) 特殊的IP地址:127.0.0.1(本地回环地址、保留地址,点分十进制)可用于简单的测试网卡是否故障。表示本机。
  B:端口号
     (1) 用于标识进程的逻辑地址。不同的进程都有不同的端口标识。
         (2) 端口:要将数据发送到对方指定的应用程序上,为了标识这些应用程序,所以给这些网络应用程序都用数字进行标识。为了方便称呼这些数字,则将这些数字                        称为端口。(此端口是一个逻辑端口)
  C: 传输协议:通讯的规则
         例如:TCP、UDP协议(好比两个人得用同一种语言进行交流)

二、传输协议 

  1、UDP:User Datagram Protocol用户数据报协议
      特点:
        a、面向无连接:传输数据之前源端和目的端不需要建立连接;
        b、每个数据报的大小都限制在64K(8个字节)以内;
        c、面向报文的不可靠协议;(即:发送出去的数据不一定会接收得到)
        d、传输速率快,效率高。
      现实生活实例:
             邮局寄件、实时在线聊天、视频会议…
 
  2、TCP:Transmission Control Protocol传输控制协议
       特点:
         a、面向连接:传输数据之前需要建立连接;
         b、在连接过程中进行大量数据传输;
         c、通过“三次握手”的方式完成连接,是安全可靠协议;
         d、传输速度慢,效率低。

三、socket通信流程

  

四、socket实现通信

  server端

#!/usr/bin/env python
# -*- coding:utf-8 -*-
# author by lh

import socket

sk=socket.socket()
address=('127.0.0.1',8000)
sk.bind(address)      # 绑定IP地址和端口
sk.listen(3)          # 确定客户端能连几个人


while True:
    conn,add=sk.accept()     # 阻塞,直到客户端有连接(如果收到的数据为空,则一直阻塞)
    while True:
        try:             # 如果在客户端直接退出的情况下,保证下一个可以连接
            da=conn.recv(1024)          # 接收信息(必须是字符串类型)
            da=str(da,'utf8')
            print(da)
            if not da:           # 判断是否收到的数据为空,为空则退出
                break
            data=input('请输入聊天信息:')
            conn.send(bytes(data,'utf8'))       # 发送信息(必须是bytes类型)
        except Exception:
            break

sk.close()

  client端

#!/usr/bin/env python
# -*- coding:utf-8 -*-
# author by lh

import socket

sk=socket.socket()
address=('127.0.0.1',8000)
sk.connect(address)         # 创建连接

while True:
    data=input('请输入聊天信息:')
    if data=='q':
        break
    sk.send(bytes(data,'utf8'))               # 发送信息(必须是bytes类型)
    da=sk.recv(1024)              # 接收信息(必须是字符串类型)
    da=str(da,'utf8')
    print('收到的信息:',da)
sk.close()

  运行结果

                        server端                                              client端

                                    

五、socket实例

  功能:实现命令在client端输入,传到server端,并且在server端执行并将运行结果(大文件)返回到客户端,防止粘包现象。        

  server端

#!/usr/bin/env python
# -*- coding:utf-8 -*-
# author by lh

import subprocess
import socket

sk=socket.socket()
address=('127.0.0.1',8000)
sk.bind(address)      # 绑定IP地址和端口
sk.listen(3)          # 确定客户端能连几个人


while True:
    conn,add=sk.accept()     # 阻塞,直到客户端有连接(如果收到的数据为空,则一直阻塞)
    while True:
        try:             # 如果在客户端直接退出的情况下,保证下一个可以连接
            da=conn.recv(1024)          # 接收信息(必须是字符串类型)
        except Exception:
            break
        if not da:           # 判断是否收到的数据为空,为空则退出
            break
        print('命令为:',str(da,'utf8'))
        obj=subprocess.Popen(str(da,'utf8'),shell=True,stdout=subprocess.PIPE)
        cmd_result=obj.stdout.read()        # 执行命令
        result_len=bytes(str(len(cmd_result)),'utf8')     # 计算执行结果的大小(将int类型转化为bytes类型)
        print('大小为:',result_len)
        conn.sendall(result_len)       # 发送信息(必须是bytes类型)
        conn.sendall(cmd_result)         # 发送执行结果

sk.close()

  client端

#!/usr/bin/env python
# -*- coding:utf-8 -*-
# author by lh


import socket

sk=socket.socket()
address=('127.0.0.1',8000)
sk.connect(address)         # 创建连接

while True:
    data=input('请输入命令:')
    if data=='q':
        break
    sk.send(bytes(data,'utf8'))               # 发送信息(必须是bytes类型)
    result_len=int(str(sk.recv(1024),'utf8'))      # 把收到的执行结果大小(bytes类型)转化为int类型
    print('大小为:',result_len)
    data=bytes()                        # 创建一个空的bytes类型
    while len(data)!=result_len:        # 当长度和执行结果长度不相等时接收数据
        recv=sk.recv(1024)              # 接收数据
        data+=recv                      #长度加每次传过来的长度
    print('命令执行结果为:',str(data,'gbk'))
sk.close()

 

posted on 2016-09-27 17:41  python屌丝的逆袭  阅读(127)  评论(0编辑  收藏  举报

导航