一. socket模塊
socket
,俗稱套接字,其實就是一個
ip
地址和端口的組合。類似于這樣的形式
(ip, port),
其中
ip
代表的是某個主機,
port
代表的是某個應(yīng)用,我們可以通過
socket
和另外的一臺主機進行通信。
關(guān)于socket
源碼的解析在
tarnado
系列文章中,正在寫中。。。。。
1. 通信的方式
tcp
通信
udp
通信
基于unix
的通信
2. socket的方法
#
暫時知道的也就這么多,之后要是在用到其他的我會繼續(xù)進行保存
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
關(guān)閉一個套接字
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
接受數(shù)據(jù)
recv_into(buffer[, nbytes[, flags]]) -- receive data (into a buffer)
接受數(shù)據(jù)到緩沖區(qū)中,
recvfrom(buflen[, flags]) -- receive data
and sender's address
recvfrom_into(buffer[, nbytes, [, flags])
-- receive data and sender'
s address (into a buffer)
sendall(data[, flags]) --
send all data
發(fā)送數(shù)據(jù)給遠端主機,
3.x
之后只能發(fā)送字節(jié)形式,因此在發(fā)送的時候一般要進行轉(zhuǎn)換
bytes
send(data[, flags]) --
send data, may
not
send all of it
也是發(fā)送數(shù)據(jù),區(qū)別在于
send
發(fā)送的不完整,隨機進行發(fā)送的,二sendall
發(fā)送的完整
sendto(data[, flags], addr) --
send data to a
given address
基于
udp
發(fā)送數(shù)據(jù)的
setblocking(0 | 1) -- set
or clear the blocking I/O flag
是否設(shè)置成阻塞模式
0
代表阻塞,
1
代表非阻塞
setsockopt(level, optname, value) -- set
socket options
設(shè)置一些
socket
的桉樹
settimeout(None | float) -- set
or clear the timeout
設(shè)置超時市場
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!
二. 簡單的聊天機器人
如果發(fā)送一個數(shù)據(jù),服務(wù)器就會給他回復(fù)一個數(shù)據(jù) +
你好
1 # -*- coding:utf-8 -*-
2 # zhou
3 # 2017/7/3
4
5
import socket
6 #
創(chuàng)建一個
server
對象
7 server_obj = socket.socket()
8 #
綁定一下端口
9 server_obj.bind(("127.0.0.1", 8888, ))
10 #
設(shè)置監(jiān)聽的等待隊列長度為
5,
當(dāng)大于
5
的時候就拒絕連接
11 server_obj.listen(5)
12
13
while
True:
14 #
等待接受客戶端的連接
,
為阻塞方式
15 conn, address = server_obj.accept()
16 #
發(fā)送歡迎信息
17 conn.sendall(bytes("
歡迎來到簡單的聊天室
..", encoding='utf-8'))
18
while
True:
19 #
接受到對面的消息就會把對面消息后面加上你好重新發(fā)送回去
20 ret = str(conn.recv(1024), encoding='utf-8')
21
if ret == 'q':
22 #
如果對面發(fā)送的為
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("
請輸入您要發(fā)送的內(nèi)容
:")
client.sendall(bytes(message,
encoding='utf-8'))
if message == 'q':
break
ret = str(client.recv(1024),
encoding='utf-8')
print(ret)
client
三. 簡單的ftp上傳
實現(xiàn)了將一個圖片上傳到服務(wù)器端
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 #
已經(jīng)接受的文件大小
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() #
關(guān)閉文件
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 #
發(fā)送文件大小
16 client.sendall(bytes(str(file_size), encoding='utf-8'))
17 client.recv(1024) #
解決粘包問題
18 #
發(fā)送文件
19
with open("1.jpg", 'rb')
as f:
20
for line
in f:
21 client.sendall(line)
22 client.close()
ftpclient
四. 粘包問題的解決
對于上面第三個ftp
上傳進行的描述,
解決粘包的問題,當(dāng)我們上傳一個文件的時候,首先上傳他的大小,當(dāng)我們上傳完大小之后要在寫一句接受的語句,而服務(wù)器端在接受到文件大小之后要給我們立馬發(fā)送一個數(shù)據(jù)用來確認,這樣我們就可以完美的將數(shù)據(jù)喝大小分割開了。
來源:
博客園