⑴ 如何在ubuntu中命令行關閉python socket伺服器
本文介紹下,在solaris 系統下,python socket server重啟後,提示埠被佔用,telnet埠失敗。這里給出一個解決方法,有需要的朋友參考下。
在solaris 系統下,socket server被重啟後,提示埠被佔用,telnet埠又是不成功的,說明服務已被關閉。
通過netstat可以看到埠還處於於fin_wait_2狀態,solaris要4分鍾才能關閉。
遇到這個問題時,可以採用如下的方法解決,以減少等待時間。
1,加上s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)。
代碼:
復制代碼代碼示例:
self.host=socket.gethostbyname(socket.gethostname())
s = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
s.bind((self.host,self.port))
s.listen(5)
2,修改系統fin_wait,time_wait的時間設置。這個時間改短,也利於系統系能。
修改方法
查看或設置:
使用get命令來確定當前時間間隔,並使用set命令將時間間隔指定為30秒。
例如:
復制代碼代碼示例:
ndd -get /dev/tcp tcp_time_wait_interval
ndd -set /dev/tcp tcp_time_wait_interval 30000
預設值:對於 Solaris 操作系統,預設等待時間間隔為 240000 毫秒(即 4 分鍾)。
建議值:60000 毫秒。
Solaris TCP_FIN_WAIT_2_FLUSH_INTERVAL
描述:
指定禁止處於FIN_WAIT_2狀態的連接保持該狀態的計時器時間間隔。
當連接比率較高時,這將累積大量的TCP/IP連接,從而導致伺服器性能下降。在高峰時間段,伺服器會發 生延遲。
如果伺服器延遲,netstat命令顯示對HTTP Server打開的許多套接字處於CLOSE_WAIT或FIN_WAIT_2狀態。
明顯的延遲可能會長達4分鍾,其間伺服器無法發送任何響應,但是CPU利用率保持很高,所有活動都在系統進程中。
查看和設置:
使用get命令來確定當前時間間隔,並使用set命令將時間間隔指定為67.5秒。
例如:
⑵ python socket recv判斷是否有數據
使用基礎數據接收法時,當與服務socket斷開連接時,會接收到空字元串。
因此,可以根據此特點,在程序中加入循環,一直接收數據,直到數據發送端關閉socket連接。
適用場景:客戶端和伺服器的鏈接為短鏈接(即一次socket通訊後連接就會關閉)。
⑶ 問一下 python 使用socket tcp 在客戶端close之後服務端的socket會怎麼樣
會被釋放去處理後面的連接,你可以在本機寫個server端,連接一下看看效果,使用socket模塊很方便的。
如果解決了您的問題請採納!
如果未解決請繼續追問
⑷ python 2.7中有沒有socketserver這個模塊
Python提供了兩個基本的socket模塊。一個是socket,它提供了標準的BSD Socket API;另一個是socketServer,它提供了伺服器中心類,可以簡化網路伺服器的開發。
本文簡要介紹socket模塊包含的類及其使用。
1.開始了解socket模塊前,先熟悉下Python的網路編程模塊主要支持的兩種Intent協議:TCP和UDP。TCP協議是一種面向連接的可靠協議,用於建立機器之間的雙向通信流。UDP協議是一種較低級別的、以數據包為基礎的協議(無連接傳輸模式)。與TCP不同,UDP信息不可靠。
他們的區別如下圖所示:左圖為TCP連接協議,右圖為UDP連接協議
2.socket模塊的部分類方法介紹
類方法
說明
socket.socket(family, type[,proto])
創建並返回一個新的 socket對象
socket.getfqdn(name)
將使用點號分隔的 IP地址字元串轉換成一個完整的域名
socket.gethostbyname(hostname)
將主機名解析為一個使用點號分隔的 IP地址字元串
socket.gethostbyname_ex(name)
它返回一個包含三個元素的元組,從左到右分別是給定地址的主要的主機名、同一IP地址的可選的主機名的一個列表、關於同一主機的同一介面的其它IP地址的一個列表(列表可能都是空的)。
socket.gethostbyaddr(address)
作用與gethostbyname_ex相同,只是你提供給它的參數是一個IP地址字元串
Socket.getservbyname(service,protocol)
它要求一個服務名(如'telnet'或'ftp')和一個協議(如'tcp'或'udp'),返回服務所使用的埠號
socket.fromfd(fd, family, type)
從現有的文件描述符創建一個 socket對象
3.socket對象的部分方法介紹
實例方法
說明
sock.bind( (adrs, port) )
將 socket綁定到一個地址和埠上
sock.accept()
返回一個客戶機 socket(帶有客戶機端的地址信息)
sock.listen(backlog)
將 socket設置成監聽模式,能夠監聽 backlog 外來的連接請求
sock.connect( (adrs, port) )
將 socket連接到定義的主機和埠上
sock.recv( buflen[, flags] )
從 socket中接收數據,最多 buflen 個字元
sock.recvfrom( buflen[, flags] )
從 socket中接收數據,最多 buflen 個字元,同時返回數據來源的遠程主機和埠號
sock.send( data[, flags] )
通過 socket發送數據
sock.sendto( data[, flags], addr )
通過 socket發送數據
sock.close()
關閉 socket
sock.getsockopt( lvl, optname )
獲得指定 socket 選項的值
sock.setsockopt( lvl, optname, val )
設置指定 socket選項的值
4.編寫socket測試程序
(a)編寫server的步驟
第一步是創建socket對象。調用socket構造函數。如:
socket = socket.socket( family, type )
family參數代表地址家族,可為AF_INET或AF_UNIX。AF_INET家族包括Internet地址,AF_UNIX家族用於同一台機器上的進程間通信。
type參數代表套接字類型,可為SOCK_STREAM(流套接字)和SOCK_DGRAM(數據報套接字)。
第二步是將socket綁定到指定地址。這是通過socket對象的bind方法來實現的:
socket.bind( address )
由AF_INET所創建的套接字,address地址必須是一個雙元素元組,格式是(host,port)。host代表主機,port代表埠號。如果埠號正在使用、主機名不正確或埠已被保留,bind方法將引發socket.error異常。
第三步是使用socket套接字的listen方法接收連接請求。
socket.listen( backlog )
backlog指定最多允許多少個客戶連接到伺服器。它的值至少為1。收到連接請求後,這些請求需要排隊,如果隊列滿,就拒絕請求。
第四步是伺服器套接字通過socket的accept方法等待客戶請求一個連接。
connection, address = socket.accept()
調 用accept方法時,socket會時入「waiting」狀態。客戶請求連接時,方法建立連接並返回伺服器。accept方法返回一個含有兩個元素的元組(connection,address)。第一個元素connection是新的socket對象,伺服器必須通過它與客戶通信;第二個元素 address是客戶的Internet地址。
第 五步是處理階段,伺服器和客戶端通過send和recv方法通信(傳輸 數據)。伺服器調用send,並採用字元串形式向客戶發送信息。send方法返回已發送的字元個數。伺服器使用recv方法從客戶接收信息。調用recv 時,伺服器必須指定一個整數,它對應於可通過本次方法調用來接收的最大數據量。recv方法在接收數據時會進入「blocked」狀態,最後返回一個字元 串,用它表示收到的數據。如果發送的數據量超過了recv所允許的,數據會被截短。多餘的數據將緩沖於接收端。以後調用recv時,多餘的數據會從緩沖區 刪除(以及自上次調用recv以來,客戶可能發送的其它任何數據)。
傳輸結束,伺服器調用socket的close方法關閉連接。
(b)編寫client的步驟
首先創建一個socket以連接伺服器:socket =socket.socket( family, type )
使用socket的connect方法連接伺服器。對於AF_INET家族,連接格式如下:
socket.connect( (host,port) )
host代表伺服器主機名或IP,port代表伺服器進程所綁定的埠號。如連接成功,客戶就可通過套接字與伺服器通信,如果連接失敗,會引發socket.error異常。
處理階段,客戶和伺服器將通過send方法和recv方法通信。
傳輸結束,客戶通過調用socket的close方法關閉連接。
5.實例源碼:python socket半雙工聊天
(a)tcpserver.py
[python] view plain
# -*- coding: cp936 -*-
#file:tcpserver.py
import socket
from time import ctime
import sys
bufsize = 1024
host = '127.0.0.1'
port = 8100
address = (host,port)
server_sock = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
server_sock.bind(address)
server_sock.listen(1)
while True:
print 'waiting for connection...'
clientsock,addr = server_sock.accept()
print 'received from :',addr
while True:
data = clientsock.recv(bufsize)
print ' 收到---->%s\n%s' %(ctime(),data)
data = raw_input("發送----->")
clientsock.send(data)
clientsock.close()
server_sock.close()
(b)tcpclient.py
[python] view plain
## -*- coding: cp936 -*-
##file:tcpclient.py
from socket import *
from time import ctime
bufsize = 1024
host = '127.0.0.1'
port = 8100
addr = (host,port)
client_sock = socket(AF_INET,SOCK_STREAM)
client_sock.connect(addr)
while True:
data = raw_input("發送---->")
if not data:
break
else:
client_sock.send(data)
data = client_sock.recv(bufsize)
print '收到---->%s\n%s' %(ctime(),data)
client_sock.close()
⑸ python非同步網路編程怎麼使socket關閉之後立即執行一段代碼
自己實現MySocket類,繼承自socket,然後重寫它的close方法,在裡面調用父類close方法,再加上你自己想做的工作,其他不要動。
⑹ 如何終止用python寫的socket服務端程序
把第二個循環放在第一個循環裡面。accept完了就收發數據,循環收發。收發完了,關閉了,就回到accept的等待狀態
⑺ linux python socket怎麼去除
原因是server端關掉了tcp連接,給client發送FIN信號,client的tcp層回了ACK,然後它的socket狀態就處於close_wait狀態。
實驗:
Python中,socket在send之前處於close_wait狀態,那麼該send不會報錯,並且執行完之後socket就closed了。再繼續調用send就會報錯。
推理:
說明python的socket.send在發送數據之前會檢查socket的狀態,如果處於close_wait,就執行close(socket)(應用層感覺不到哦),然後正常退出。所以再次send時,會拋出異常。
為什麼會一直處close_wait狀態?
當socket處於close_wait時,必須由應用層調用close(socket),發送FIN給server端才能變為LAST_ACK,接收到server端回應的ACK後,才變為CLOSED。如果應用層不調用close(),那麼socket會一直處於close_wait。[1]
如果我在python中不斷循環去調用socket.sendall(),那麼在socket變為close_wait後,通過socket.sendall()也會關閉socket,為什麼它還是一直處在close_wait狀態呢?
原因在於當sendall(data)的data比較大,在data被發送一半時,連接被server端斷掉了。那麼sendall(data)會一直卡在那,也就不會執行到sendall的開始處,去判斷socket狀態,確定是否關閉socket了。
簡單而言,就是socket在變為close_wait之後,根本沒有調用sendall()去關閉socket。
⑻ python 不關閉socket連接會怎麼樣
如果不主動關閉socket的話,系統不會自動關閉的,除非當前進程掛掉了,操作系統把佔用的socket回收了才會關閉。
為什麼需要心跳連接主要是判斷當前連接是否是有效的、可被使用的。在實際應用中假設一段時間沒有數據傳輸時候理論上說應該連接是沒有問題的,但是網路復雜,中途出現問題也是常見的,網線被掐斷了、對方進程掛掉了、頻繁丟包等,這時候TCP連接是不可使用的,但是對於應用層並不知道,如果需知道網路情況則要很復雜的超時進行了解,TCP從底層就實現了這樣的功能。心跳機制是TCP在一段時間間隔後發送確定連接端是否還存在,如果存在的話就會回傳一個包確定網路有效,如果心跳包有問題,則通知上層應用當前網路有問題了。
⑼ Python中socket里的.recv()函數問題
可以通過setsockopt,或者更簡單的setblocking,
settimeout設置。阻塞式的socket的recv服從這樣的規則:
當緩沖區內有數據時,立即返回所有的數據;當緩沖區內無數據時,阻塞直到緩沖區中有數據。非阻塞式的socket的recv服從的規則則是:
當緩沖區內有數據時,立即返回所有的數據;當緩沖區內無數據時,產生EAGAIN的錯誤並返回(在Python中會拋出一個異常)。兩種情況都不會返回空字元串,返回空數據的結果是對方關閉了連接之後才會出現的。