1. 程式人生 > >Python系列8之socket

Python系列8之socket

art keyword http tps dal input port pytho ima

目錄

  socket  

  簡單的聊天機器人

  簡單的ftp上傳

  粘包問題的解決

一. socket模塊

  socket,俗稱套接字,其實就是一個ip地址和端口的組合。類似於這樣的形式(ip, port),其中ip代表的是某個主機,port代表的是某個應用,我們可以通過socket和另外的一臺主機進行通信。

  關於socket源碼的解析在tarnado系列文章中,正在寫中。。。。。

  1. 通信的方式

    tcp通信

    udp通信

    基於unix的通信

  2. socket的方法 

# 暫時知道的也就這麽多,之後要是在用到其他的我會繼續進行保存
    Methods of socket objects (keyword arguments not
allowed): _accept() -- accept connection, returning new socket fd and client address bind(addr) -- bind the socket to a local address 給本地地址綁定一個socket套接字 close() -- close the socket 關閉一個套接字 connect(addr) -- connect the socket to a remote address 連接到遠端主機 connect_ex(addr)
-- connect, return an error code instead of an exception dup() -- return a new socket fd duplicated from fileno() fileno() -- return underlying file descriptor getpeername() -- return remote address [*] getsockname() -- return local address getsockopt(level, optname[, buflen]) -- get socket options gettimeout()
-- return timeout or None listen([n]) -- start listening for incoming connections recv(buflen[, flags]) -- receive data 接受數據 recv_into(buffer[, nbytes[, flags]]) -- receive data (into a buffer) 接受數據到緩沖區中, recvfrom(buflen[, flags]) -- receive data and senders address recvfrom_into(buffer[, nbytes, [, flags]) -- receive data and senders address (into a buffer) sendall(data[, flags]) -- send all data 發送數據給遠端主機,3.x之後只能發送字節形式,因此在發送的時候一般要進行轉換bytes send(data[, flags]) -- send data, may not send all of it 也是發送數據,區別在於send發送的不完整,隨機進行發送的,二sendall發送的完整 sendto(data[, flags], addr) -- send data to a given address 基於udp發送數據的 setblocking(0 | 1) -- set or clear the blocking I/O flag 是否設置成阻塞模式0 代表阻塞,1代表非阻塞 setsockopt(level, optname, value) -- set socket options 設置一些socket的案樹 settimeout(None | float) -- set or clear the timeout 設置超時市場 shutdown(how) -- shut down traffic in one or both directions if_nameindex() -- return all network interface indices and names if_nametoindex(name) -- return the corresponding interface index if_indextoname(index) -- return the corresponding interface name [*] not available on all platforms!

二. 簡單的聊天機器人

  如果發送一個數據,服務器就會給他回復一個數據 + 你好

技術分享
 1 # -*- coding:utf-8 -*-
 2 # zhou
 3 # 2017/7/3
 4 
 5 import socket
 6 # 創建一個server對象
 7 server_obj = socket.socket()
 8 # 綁定一下端口
 9 server_obj.bind(("127.0.0.1", 8888, ))
10 # 設置監聽的等待隊列長度為5,當大於5的時候就拒絕連接
11 server_obj.listen(5)
12 
13 while True:
14     # 等待接受客戶端的連接,為阻塞方式
15     conn, address = server_obj.accept()
16     # 發送歡迎信息
17     conn.sendall(bytes("歡迎來到簡單的聊天室..", encoding=utf-8))
18     while True:
19         # 接受到對面的消息就會把對面消息後面加上你好重新發送回去
20         ret = str(conn.recv(1024), encoding=utf-8)
21         if ret == q:
22             # 如果對面發送的為q就退出
23             break
24         conn.sendall(bytes(ret + ",你好", encoding=utf-8))
server 技術分享
# -*- coding:utf-8 -*-
# zhou
# 2017/7/3

import socket

client = socket.socket()
client.connect(("127.0.0.1", 8888, ))
# 接受歡迎信息並打印
ret = str(client.recv(1024), encoding=utf-8)
print(ret)

while True:
    message = input("請輸入您要發送的內容:")
    client.sendall(bytes(message, encoding=utf-8))
    if message == q:
        break
    ret = str(client.recv(1024), encoding=utf-8)
    print(ret)
client

三. 簡單的ftp上傳

  實現了將一個圖片上傳到服務器端

技術分享
 1 # -*- coding:utf-8 -*-
 2 # zhou
 3 # 2017/7/2
 4 
 5 import socket
 6 
 7 server = socket.socket()
 8 server.bind(("127.0.0.1", 9998, ))  # 綁定ip
 9 server.listen(5)
10 
11 while True:
12     conn, address = server.accept()
13     # 連接之後首先接收文件大小
14     file_size = int(str(conn.recv(1024), encoding=utf-8))
15     # 用來解決粘包問題的
16     conn.sendall(bytes("1001", encoding=utf-8))
17     # 已經接受的文件大小
18     has_size = 0
19     num = 1
20     # 連接之後接收文件
21     f = open("new.jpg", wb)
22     while True:
23         num += 1
24         if file_size == has_size:
25             break
26         data = conn.recv(1024)
27         f.write(data)
28         has_size += len(data)
29     f.close()   # 關閉文件
ftpserver

技術分享
 1 # -*- coding:utf-8 -*-
 2 # zhou
 3 # 2017/7/2
 4 
 5 
 6 import os
 7 import socket
 8 
 9 client = socket.socket()
10 
11 client.connect(("127.0.0.1", 9998), )
12 # 傳送文件大小
13 file_size = os.stat("1.jpg").st_size
14 print(file_size)
15 # 發送文件大小
16 client.sendall(bytes(str(file_size), encoding=utf-8))
17 client.recv(1024)   # 解決粘包問題
18 # 發送文件
19 with open("1.jpg", rb) as f:
20     for line in f:
21         client.sendall(line)
22 client.close()
ftpclient

四. 粘包問題的解決

  對於上面第三個ftp上傳進行的描述,

  解決粘包的問題,當我們上傳一個文件的時候,首先上傳他的大小,當我們上傳完大小之後要在寫一句接受的語句,而服務器端在接受到文件大小之後要給我們立馬發送一個數據用來確認,這樣我們就可以完美的將數據喝大小分割開了。

  技術分享

Python系列8之socket