python網絡編程基礎

  Socket(套接字)始於Unix,即人們所說的BSD Unix。socket家族有兩種:基於文件系統的和基於網絡的。第一種是基於文件系統的,地址家族表示爲:AF_UNIX(或AF_LOCAL);第二種是網絡Socket,是基於網絡的,地址家族表示爲AF_INET(AF_INET6表示ipv6)。python

  在Python 2.5 中加入了一種 Linux 套接字的支持:AF_NETLINK(無鏈接[見下])套接字家族讓用戶代碼與內核代碼之間的 IPC 能夠使用標準 BSD 套接字接口。Python 只支持 AF_UNIX,AF_NETLINK,和 AF_INET 家族。這裏將介紹使用最普遍的一個:AF_INET。服務器

  根據套接字類型,能夠分爲面向鏈接的和無鏈接的。網絡

  面向鏈接的,在通信以前需創建一條鏈接,這種通信方式提供了順序的,可靠的,不會重複的數據傳輸,並且也不會被加上數據邊界。實現這種鏈接的主要協議就是傳輸控制協議(即 TCP),其對應的套接字類型爲 SOCK_STREAM。套接字使用 Internet 協議(IP)來查找網絡中的主機,即TCP/IP協議來支持面向鏈接套接字。多線程

  無鏈接的,無需創建鏈接就能夠進行通信。實現這種鏈接的主要協議就是用戶數據報協議(即 UDP) ,指定套接字類型爲 SOCK_DGRAM。套接字使用 Internet 協議來查找網絡中的主機,即UDP/IP協議來支持無鏈接套接字。socket

 

  1. socket()模塊函數tcp

  建立socket()套接字的語法以下:函數

  socket(socket_family, socket_type, protocol=0)oop

  socket_family通常爲AF_UNIX或者AF_INET,socket_type能夠是SOCK_STREAM或者SOCK_DGRAM,protocol通常不填,默認爲0。this

  因爲socket模塊中有太多的屬性,這裏使用"from socket import *"以減小代碼長度。spa

  建立一個TCP/IP的套接字:

  tcpsocket = socket(AF_INET, SOCK_STREAM)

  一樣的,建立一個UDP/IP的套接字:

  udpsocket = socket(AF_INET, SOCK_STREAM)

  

  2. 套接字對象(內建)方法

  python中經常使用的套接字對象函數以下:

 

  3. 基於TCP的C/S模型

  3.1 建立TCP服務端

  TCP服務端的通常設計流程以下:

ss = socket()             # 建立服務器套接字
ss.bind()                 # 綁定地址到套接字
ss.listen()               # 監聽鏈接
inf_loop():               # 服務器端無限循環
  cs = ss.accept()      # 接受客戶端鏈接
comm_loop:                # 通訊循環
  cs.recv() / cs.send() # 傳輸數據(發送/接受)
cs.close()                # 關閉客戶端套接字
ss.close()                # 關閉服務器端套接字(可選)

  3.2 建立TCP客戶端

  TCP客戶端的通常設計流程以下:

cs = socket()             # 建立客戶端套接字
cs.connect()              # 嘗試鏈接服務器
comm_loop:                # 通訊循環
  cs.send() / cs.recv()  # 傳輸數據(發送/接受)
cs.close()                # 關閉客戶端套接字

  3.3 TCP的C/S套接字模型

  下面是一個完整的C/S套接字模型。服務端採用多線程來處理客戶端的請求,而且使用setsockopt()函數達到端口複用。

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

import socket
import threading

bind_ip = '0.0.0.0'
bind_port = 6666

server = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
server.setsockopt(socket.SOL_SOCKET,socket.SO_REUSEADDR, 1)
server.bind((bind_ip, bind_port))
server.listen(5)
print '[*] Listening on %s:%d' % (bind_ip, bind_port)

# this is our client-handling thread
def handle_client(client_socket):
      # print out what the client sends
      request = client_socket.recv(1024)
      print '[*] Received: %s' % request
      # send back a packet
      client_socket.send('ACK!')
      client_socket.close()

while True:
      client, addr = server.accept()
      print '[*] Accept connection from: %s:%d' % (addr[0], addr[1])
      # spin up our client thread to handle incoming data
      client_handler = threading.Thread(target=handle_client, args=(client,))
      client_handler.start()

 

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

import socket
target_host = '127.0.0.1'
target_port = 6666

# create a socket object
client = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

# connect the client
client.connect((target_host, target_port))

# send some data
client.send('hehe, just for a test!')

# receive some data
response = client.recv(1024)

print response

 

  4. 基於UDP的C/S模型

  4.1  建立一個UDP服務器

ss = socket()                          # 建立一個服務器套接字
ss.bind()                              # 綁定服務器套接字
inf_loop:                              # 服務器無限循環
  cs = ss.recvfrom() / ss.sendto()    # 傳輸數據(接受/發送)
ss.close()

  4.2 建立一個UDP客戶端

cs = socket()                           # 建立客戶端套接字
comm_loop:                              # 通訊循環  
    cs.sendto() / cs.recvfrom()         # 傳輸數據(發送/接受)
cs.close()                              # 關閉客戶端套接字

  4.3 TCP的C/S套接字模型

  下面是一個簡單的UDP套接字的服務端和客戶端程序

 

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

from socket import *

HOST = ''
PORT = 6666
ADDR = (HOST, PORT)

server = socket(AF_INET, SOCK_DGRAM)
server.bind(ADDR)

while True:
    print '[*] Waiting for message...'
    data, addr = server.recvfrom(1024)
    print '[*] Received from: %s\n%s' % (addr, data)
    server.sendto('Recvice message ok!',addr)

 

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

from socket import *

HOST = '127.0.0.1'
PORT = 6666
ADDR = (HOST, PORT)

client = socket(AF_INET, SOCK_DGRAM)
while True:
    data = raw_input('> ')
    if not data:
        break
    client.sendto(data,ADDR)
    data, ADDR = client.recvfrom(1024)
    if not data:
        break
    print data

client.close()  
相關文章
相關標籤/搜索