手机版
你好,游客 登录 注册 搜索
背景:
阅读新闻

Python下基于Sokcet的TCP通信——入门篇

[日期:2017-10-29] 来源:Linux社区  作者:vathe [字体: ]

环境

Python版本:2.7

IDE:pycharm

TCP/UDP协议均为传输层的协议,绝大部分应用程序之间的通信都是使用TCP或UDP,故而在网络通信中及其重要,想详细了解他们之间的差异,可参考 http://www.linuxidc.com/Linux/2017-10/148095.htm

1.模拟后台程序,实现浏览器访问

Server端代码

# coding=utf-8
import socket


def handle_request(client):
    buf = client.recv(1024)
    client.send("HTTP/1.1 200 OK\r\n\r\n")      # 此句允许浏览器访问
    client.send("Hello, TCP Socket ")                  # 发送要显示的内容


def main():
    sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    sock.bind(('localhost', 8090))              # 设定ip(或者域名)和端口号
    sock.listen(2)                              # 设置最大并发数

    while 1:
        conn, address = sock.accept()   # 接收请求
        handle_request(conn)            # 处理请求
        conn.close()                    # 关闭连接


if __name__ == '__main__':
    main() 

使用浏览器访问 localhost:8090

2.模拟机器猫程序(客户端发送信息,从服务端返回源数据)

A. ServerTCP.py代码

# coding=utf-8
import socket


def handle_request(conn):
    conn.send("server: hello, let's start ")
    flag = True
    while flag:
        data = conn.recv(1024)
        if data == 'exit':
            flag = False
        else:
            conn.sendall(data)

def main():
    sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    sock.bind(('localhost', 8091))  # 设定ip(或者域名)和端口号
    sock.listen(2)  # 设置最大并发数

    while 1:
        conn, address = sock.accept()  # 接收请求
        print address,
        handle_request(conn)  # 处理请求
        conn.close()  # 关闭连接


if __name__ == '__main__':
    main()

 

B.ClientTCP.py

# coding:utf-8
import socket

client = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
address = ('localhost', 8091)
client.connect(address)
while 1:
    data = client.recv(1024)
    # client.send('client: ok, let\'s begin ')
    print data
    inp = raw_input('client:')
    client.send(inp)
    if inp == 'exit':      # 输入exit,退出
        break 

C.两程序交互结果

 

3.socket模块中的socket类简要分析

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

参数一:地址类型

  socket.AF_INET, 表示使用IPv4类型的IP, 默认类型

  socket.AF_INET6, 表示使用IPv6类型的IP

  socket.AF_UNIX, 表示使用Unix系统中同一台设备中两进程通信的socket

参数二:数据包格式

  socket.SOCK_STREAM  流式socket , for TCP (默认)

  socket.SOCK_DGRAM   数据报式socket , for UDP

  socket.SOCK_RAW 原始套接字,普通的套接字无法处理ICMP、IGMP等网络报文,而SOCK_RAW可以;其次,SOCK_RAW也可以处理特殊的IPv4报文;此外,利用原始套接字,可以通过IP_HDRINCL套接字选项由用户构造IP头。

  socket.SOCK_RDM 是一种可靠的UDP形式,即保证交付数据报但不保证顺序。SOCK_RAM用来提供对原始协议的低级访问,在需要执行某些特殊操作时使用,如发送ICMP报文。SOCK_RAM通常仅限于高级用户或管理员运行的程序使用。

  socket.SOCK_SEQPACKET 可靠的连续数据包服务

 

socket.bind(address)

  固定地址,地址包括主机和端口。主机可使用ip或域名标识。

socket.listen(backlog)

  设置最最大并发数

socket.connect(address)/socket.connect_ex(address)

  客户端请求建立连接,address表示地址,两者的区别是,如果连接出现异常,前者直接报出异常,后者返回错误码,程序继续运行

conn, address = socket.accept()

  服务端接收请求建立起连接,返回连接和地址。

socket.close()

  关闭连接

sk.recv(bufsize[,flag])

  接受套接字的数据。数据以字符串形式返回,bufsize指定最多可以接收的数量。

sk.recvfrom(bufsize[.flag])

  与recv()类似,但返回值是(data,address)。

sk.send(string[,flag])

  将string中的数据发送到连接的套接字。返回值是要发送的字节数量,该数量可能小于string的字节大小。即:可能未将指定内容全部发送。

sk.sendall(string[,flag])

  将string中的数据发送到连接的套接字,但在返回之前会尝试发送所有数据。成功返回None,失败则抛出异常。

      内部通过递归调用send,将所有内容发送出去。

sk.sendto(string[,flag],address)

  将数据发送到套接字,address是形式为(ipaddr,port)的元组,指定远程地址。返回值是发送的字节数。该函数主要用于UDP协议。

本文永久更新链接地址http://www.linuxidc.com/Linux/2017-10/148096.htm

linux
本文评论   查看全部评论 (0)
表情: 表情 姓名: 字数

       

评论声明
  • 尊重网上道德,遵守中华人民共和国的各项有关法律法规
  • 承担一切因您的行为而直接或间接导致的民事或刑事法律责任
  • 本站管理人员有权保留或删除其管辖留言中的任意内容
  • 本站有权在网站内转载或引用您的评论
  • 参与本评论即表明您已经阅读并接受上述条款