![](/img/trans.png)
[英]How to convert NSInputStream to NSString or how to read NSInputStream
[英]Should [nsInputStream read:…] return if [nsInputStream close] is called by another thread?
在我看來,如果流被另一個線程關閉,而與套接字連接的另一端無關,則任何NSInputStream對象都應該從其read:方法中彈出。 但是在某些情況下,這似乎並不正確。 似乎除非對方在連接之前至少先發送了至少一次內容,否則read:方法將不會響應流關閉。
打開連接的代碼:
// Open the socket...
CFStreamCreatePairWithSocketToHost(NULL, Host, Port, &readStream, &writeStream);
// Create NSStream objects for our use...
inputStream = (NSInputStream *)readStream;
outputStream = (NSOutputStream *)writeStream;
// take ownership of the NSStream objects...
[inputStream retain];
[outputStream retain];
// open the streams....
[inputStream open];
[outputStream open];
關閉連接的代碼:
// Close the streams...
[inputStream close];
[outputStream close];
// Release ownership...
[outputStream release];
[inputStream release];
// clear reference values...
outputStream = nil;
inputStream = nil;
在接收線程中:
-(uint8_t) GetByte
{
uint8_t c;
int N = [inputStream read:&c maxLength:1];
if ( N < 1 )
@throw [[TcpClientException alloc] init];
return c;
}
當我從主線程關閉流時,接收線程保留在read方法中。 最終它超時並崩潰。 甚至崩潰也不會導致拋出任何類型的對象(我試圖包圍代碼以捕獲任何內容(id)卻一無所獲)。
每次關閉流時,如何可靠地強制讀取彈出?
另外:
我在帶有5.1 iPad模擬器的ML上使用XCODE 4.4.1。
如果我僅關閉inputStream而沒有釋放或設置為nil,那么也會發生此問題。
經過大量調查,我在SO上遇到了另一個線程,該線程提示了答案:由於本地設備正在斷開連接,因此不會有任何通過read方法傳遞的來自連接(來自遠程端點)的事件。 這個想法是,由於本地設備負責斷開連接,因此它將知道它不應該進入讀取方法(不會讀取任何內容)。 這有點出乎意料,因為當接收器線程已經在read方法中時,用戶可能會斷開連接。 但是... iOS的設計顯然不依賴於接收器線程,而是依賴於運行循環中的事件(這是另一個問題,但我不想在這里討論)。 具體來說,給定運行循環中的事件說有可用數據,則您可以輸入read方法。 因此,您永遠不會輸入read並掛起等待第一個字節。 這與我過去在Windows平台上完成的套接字編程完全不同。 但是到目前為止,我所做的所有實驗都表明這是問題所在。 我有一個現在可以運行的解決方案,該解決方案依賴於工作線程中來自運行循環的流中的事件,因此網絡流量不會干擾GUI(main)線程。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.