2009-09-14 81 views
2

我在嘗試在python TCP服務器和C++ TCP客戶端之間通信時遇到問題。 第一次通話結束後,通話正常,隨後的通話會引發問題。在python tcp服務器和C++客戶端之間通話

就WinSock而言,send()函數正常工作,它返回適當的長度並且WSAGetLastError()不會返回任何重要的東西。

但是,當使用wireshark觀看數據包時,我注意到第一個呼叫發送兩個數據包,一個是PSH,其中包含所有數據的ACK,另一個是後面的ACK,但後來的呼叫不工作,只發送PSH,ACK數據包,而不是後續的ACK數據包

接收計算機wireshark corroborates這一點,和python服務器什麼都不做,它沒有任何數據從套接字出來,我無法深入調試,因爲套接字是一個本地類

當我運行一個c + +客戶端和一個c + +服務器(一個python會做什麼的黑客複製品)時,客戶忠實地一次發送PSH,ACk和ACK數據包,即使在第一次通話之後。

winsock發送函數應該總是發送一個PSH,ACK和一個ACK嗎? 如果是這樣,爲什麼當連接到我的C++服務器而不是python服務器時會這樣做? 有沒有人有類似的問題?

+0

在服務器的任一版本中,您是否看到從服務器發送的確認?你提到客戶發送的應答不應該發生,除非你從服務器獲得某些東西。你確定python應用程序的行爲? – stonemetal 2009-09-14 19:10:19

回答

2

客戶端發送一個PSH,ACK然後 服務器發送一個PSH,ACK和FIN ,PSH,ACK

有一個FIN,那麼你的服務器的Python版本是否會在初始讀取後立即關閉連接?

如果你沒有明確地關閉服務器的套接字,那麼服務器的遠程套接字變量很可能超出了範圍,因此關閉它(並且這個錯誤在C++版本中不存在)?

假設是這樣的話,我可能會導致一個非常類似的TCP序列與此代碼服務器:

# server.py 
import socket 
from time import sleep 

def f(s): 
     r,a = s.accept() 
     print r.recv(100) 

s = socket.socket() 
s.bind(('localhost',1234)) 
s.listen(1) 

f(s) 
# wait around a bit for the client to send it's second packet 
sleep(10) 

這對於客戶端:

# client.py 
import socket 
from time import sleep 

s = socket.socket() 
s.connect(('localhost',1234)) 

s.send('hello 1') 
# wait around for a while so that the socket in server.py goes out of scope 
sleep(5) 
s.send('hello 2') 

啓動數據包嗅探器,然後運行server.py,然後運行client.py。 tcpdump -A -i lo的輸出結果符合您的觀察結果:

tcpdump: verbose output suppressed, use -v or -vv for full protocol decode 
listening on lo, link-type EN10MB (Ethernet), capture size 96 bytes 
12:42:37.683710 IP localhost:33491 > localhost.1234: S 1129726741:1129726741(0) win 32792 <mss 16396,sackOK,timestamp 640881101 0,nop,wscale 7> 
E..<[email protected]@...............CVC.........I|[email protected] 
&3.......... 
12:42:37.684049 IP localhost.1234 > localhost:33491: S 1128039653:1128039653(0) ack 1129726742 win 32768 <mss 16396,sackOK,timestamp 640881101 640881101,nop,wscale 7> 
E..<[email protected]@.<.............C<[email protected] 
&3..&3...... 
12:42:37.684087 IP localhost:33491 > localhost.1234: . ack 1 win 257 <nop,nop,timestamp 640881102 640881101> 
[email protected]@...............CVC.C<......1...... 
&3..&3.. 
12:42:37.684220 IP localhost:33491 > localhost.1234: P 1:8(7) ack 1 win 257 <nop,nop,timestamp 640881102 640881101> 
E..;[email protected]@...............CVC.C<......./..... 
&3..&3..hello 1 
12:42:37.684271 IP localhost.1234 > localhost:33491: . ack 8 win 256 <nop,nop,timestamp 640881102 640881102> 
E..4.(@[email protected]<..CVC.....1}..... 
&3..&3.. 
12:42:37.684755 IP localhost.1234 > localhost:33491: F 1:1(0) ack 8 win 256 <nop,nop,timestamp 640881103 640881102> 
E..4.)@[email protected]<..CVC.....1{..... 
&3..&3.. 
12:42:37.685639 IP localhost:33491 > localhost.1234: . ack 2 win 257 <nop,nop,timestamp 640881104 640881103> 
[email protected]@...............CVC.C<......1x..... 
&3..&3.. 
12:42:42.683367 IP localhost:33491 > localhost.1234: P 8:15(7) ack 2 win 257 <nop,nop,timestamp 640886103 640881103> 
E..;[email protected]@...............CVC.C<......./..... 
&3%W&3..hello 2 
12:42:42.683401 IP localhost.1234 > localhost:33491: R 1128039655:1128039655(0) win 0 
E..([email protected]@.<.............C<......P...b... 

9 packets captured 
27 packets received by filter 
0 packets dropped by kernel 
+0

這肯定是問題 即時使用xmlrpc服務器作爲我的python服務器,顯然這是一個單一的服務實體? – DanJ 2009-09-15 12:53:20

0

你發送了多大的數據包?

如果他們很小 - 可能是Nagle's Algorith & Delayed ACK Algorithm是你的頭痛?從你所描述認爲延遲的ACK參與...

+0

我告訴wireshark查看服務器發回的所有內容,我發現第一次發送/接收時,客戶端發送一個PSH,ACK,然後服務器發送一個PSH,ACK和一個FIN,PSH, ACK返回,我的客戶端用PSH,ACK進行響應,然後對於第二個呼叫,我發送了我的第一個PSH,ACK,並且服務器響應一個RST獲得連接重置請求,這發生在服務器沒有收到確認? 這可能是缺乏雙緩衝的結果嗎? – DanJ 2009-09-14 19:35:43