socket编程

socket是什么

  1. 首先,我们要知道网络中进程是如何通信的,在TCP/IP协议簇中,网络层的IP地址可以标识一台计算机在网络中的地址,而传输层的”协议+端口”则能够唯一的标识主机中的应用程序(进程)。这样(ip address, protocol, port)就可以标识出网络的进程了。
  2. 现行TCP/IP体系结构比较简单,只有四层,即 应用层,传输层,网际层,网络接口层。
    |应用层|HTTP, …,SMTP,DNS…RTP|
    |:—-|:————:|
    |运输层|TCP, UDP|
    |网际层| IP协议|
    |网络接口层|网络接口1…n|
    即下图所示
    TCP/IP协议簇之间的关系
    但是在这当中,我们并没有看到socket在哪里,事实上,socket是应用层与TCP/IP协议族通信的中间软件抽象层,它是一组接口。
    Socket抽象层

客户端

  • 创建socket连接
    1
    2
    3
    4
    5
    import socket
    s = socker.socket(socket.AF_INET, socket.SOCK_STREAM)
    #socket(family,type[,protocal]) 使用给定的地址族、套接字类型、协议编号(默认为0)来创建套接字。
    #family:AF_INET(用于 Internet 进程间通信) 或者 AF_UNIX(用于同一台机器进程间通信)
    #type: SOCKET_STREAM(流式套接字,主要用于 TCP 协议)或者SOCKET_DGRAM(数据报套接字,主要用于 UDP 协议)

如果创建socker失败,会抛出一个socket.error的异常,必须进行处理

1
2
3
4
5
6
7
8
9
10
11
import socket   #for sockets
import sys #for exit

try:
#create an AF_INET, STREAM socket (TCP)
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
except socket.error, msg:
print ' 创建socket错误,错误码:' + str(msg[0]) + ' , 错误原因: ' + msg[1]
sys.exit();

print 'socket建立成功 ^_^'

  • 连接服务器
    连接服务器时需要知道其IP地址以及端口号
    这里以github为例

    1
    2
    3
    4
    5
    6
    host = 'www.github.com'
    port = 80
    sip = socket.gethostbyname(host)
    s.connect((sip, port))
    print 'socket 连接到:,' + host +'的IP地址为:' + sip
    #Socket Connected to www.github.com on ip 192.30.252.130
  • 发送消息

    1
    2
    3
    4
    5
    6
    #请求网页内容
    message = "GET / HTTP/1.1\r\n\r\n"
    s.sendall(message)

    #sendall(data[, flags]) -- send all data
    #send(data[, flags]) -- send data, may not send all of it
  • 接收消息

    1
    2
    3
    4
    5
    6
    7
    8
    '''
    recv(buflen[, flags]) -- receive data
    | recv_into(buffer[, nbytes[, flags]]) -- receive data (into a buffer)
    | recvfrom(buflen[, flags]) -- receive data and sender's address
    | recvfrom_into(buffer[, nbytes, [, flags])
    | -- receive data and sender's address (into a buffer)
    '''

    reply = s.recv(4096)
    • 关闭socket连接
      1
      s.close()

服务器端

  • 打开socket

  • 绑定socket

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    import socket
    import sys
    HOST = '' # Symbolic name meaning all available interfaces
    PORT = 8888 # Arbitrary non-privileged port
    s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    print 'Socket created'
    s.bind((HOST, PORT))
    print 'Socket bind complete'
    ```
    - 监听连接
    ```python
    # listen(n) -- start listening for incoming connections
    s.listen(5)
  • 接收连接

    1
    2
    3
    #accept() -- accept a connection, returning new socket and client address
    conn, addr = s.accept()
    print 'Connected with ' + addr[0] + ':' + str(addr[1])

参考文献:

1. Linux socket 编程,第一部分
2.Linux Socket编程(不限Linux)
3.python socket编程详细介绍
4.socket library