簡體   English   中英

如何在套接字之間正確中繼TCP流量?

[英]How to correctly relay TCP traffic between sockets?

我正在嘗試編寫一些Python代碼,它將在兩個TCP套接字之間建立一個不可見的中繼。 我目前的技術是設置兩個線程,每個線程讀取並隨后在特定方向上一次寫入1kb數據(即A到B的1個線程,B到A的1個線程)。

這適用於某些應用程序和協議,但它並非萬無一失 - 有時特定應用程序在運行此基於Python的中繼時的行為會有所不同。 有些甚至崩潰。

我認為這是因為當我完成對套接字A的讀取時,在那里運行的程序認為它的數據已經到達B,而實際上我 - 中間的狡猾的人 - 尚未將它發送給B.在B未准備好接收數據的情況下(即send()阻塞一段時間),我們現在處於A認為已成功向B發送數據的狀態,但我仍然保留數據,等待用於執行send()調用。 我認為這是我在某些應用程序中發現的行為差異的原因,同時使用我當前的中繼代碼。 我錯過了什么,或聽起來是否正確?

如果是這樣,我真正的問題是:有沒有解決這個問題的方法? 當我們知道B准備好接收數據時,是否可以只讀取套接字A? 或者是否有另一種技術可用於在[已經打開和建立的] TCP套接字之間建立真正“隱形”的雙向中繼?

當我們知道B准備好接收數據時,是否可以只讀取套接字A?

當然:在套接字A和B上使用select.select (如果它返回說只有其中一個已經准備就緒,在另一個套接字上使用它),並且只有當你知道它們都准備就緒時才從A讀取並寫入B. 例如:

import select

def fromAtoB(A, B):
    r, w = select.select([A], [B], [])
    if not r: select.select([A], [], [])
    elif not w: select.select([], [B], [])
    B.sendall(A.recv(4096))

我不認為這可能是你的問題。

一般情況下,發送應用程序無法判斷接收應用程序何時實際調用recv()來讀取數據:發送方的send()可能已經完成,但源和目標操作系統中的TCP實現將進行緩沖,流量控制,轉播等

即使沒有中間的繼電器,A“只考慮其數據已經到達B”的唯一方法是收到B的回復說“是的,我得到了它”。

也許你代理的應用程序編寫得很糟糕。

例如,如果我調用recv(fd, buf, 4096, 0); 我不承諾4096字節。 系統盡最大努力提供它。

如果1k不是應用程序的recvsend大小的倍數,並且應用程序被破壞,那么將發送到1k塊的數據分組將破壞應用程序。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM