2015-06-05 187 views
0

我正在爲學校開發一個程序,並且在套接字方面存在一些問題。因爲我認爲這是問題,所以我粘貼了我的程序中的寫入和讀取命令。該程序應採取明文文件並使用提供的密鑰對其進行加密。使用套接字發送和接收數據c

我的問題:當我使用「client [plaintext] [key] [port]」執行程序時,程序返回「從客戶端讀取數據 - 140字節」,然後掛起。我可以點擊ctrl-c,程序爲ptext和ktext輸出正確的輸出,並將37個字節發送回客戶端(這是正確的字節數)。我覺得加密文本應該打印,但它不會。

兩個問題:

1)爲什麼程序掛起?

2)爲什麼看起來數據是從服務器寫入客戶端,但客戶端不讀取任何數據?

非常感謝您提供的任何幫助。

CLIENT

n = write(sockfd,ptext,strlen(ptext)); 

bzero(crypt_text, BUF_MAX); 
bzero(buffer, BUF_MAX); 

while((n = read(sockfd,buffer,BUF_MAX))>0){ 
    printf("Reading data from Server -- %d bytes\n",n); 
    strcat(crypt_text, buffer); 
    bzero(buffer,BUF_MAX); 
} 
if (n < 0){ 
    error("ERROR reading from socket"); 
} 

printf("%s", crypt_text); 

服務器

while((n = read(newsockfd,buffer,512))>0){ 
    printf("Reading data from client -- %d bytes\n",n); 
    strcat(full_text, buffer); 
    bzero(buffer,BUF_MAX); 
} 
if (n < 0){ 
    error("ERROR reading from socket"); 
} 

bzero (ptext,BUF_MAX); 
bzero (ktext, BUF_MAX); 
strcpy(ptext, strtok(full_text,"[")); 
strcpy(ktext, strtok(NULL, "[")); 

printf("ptext length ==%s %d\n\n",ptext,strlen(ptext)); //Prints the correct  plain text 
printf("ktext length ==%s %d\n\n",ktext,strlen(ktext)); //prints the correct key 

crypt_text = encrypt(ptext, ktext); 

n = write(newsockfd,crypt_text,strlen(crypt_text)); 
printf("WRITE TO CILENT ==== %d",n); //This returns the correct number of  bytes that should be sent back to client 

if (n < 0){ 
    error("ERROR writing to socket"); 
} 
+0

您是否嘗試過調試器? 「爲什麼我的程序不能正常工作?」問題在SO上不鼓勵。 –

+0

要回答2)您的程序正在從服務器讀取數據到緩衝區,它不會直接讀取您的程序。有選項可以「刷新」緩衝區並關閉緩衝區。那麼你可能會看到你的輸出。 – amza

+0

'read()'是阻塞I/O的一部分。 IIRC你不能像這樣使用'read()'。它會一直阻止ie.keep等待客戶端再次寫入內容 –

回答

1

原樣,您的客戶端和服務器會一直掛在等待對方。這是因爲read()在默認情況下會阻塞,直到有新數據可用於從文件中讀取(在本例中爲套接字)。

仔細的代碼看:

  1. 客戶端寫入一旦插入插座進入讀取循環
  2. 服務器只從套接字讀取之前(當然,再往下有一個write(),但它永遠不會達到它)。循環第一次在服務器上運行時,它將讀取客戶端最初寫入套接字的數據。
  3. 服務器處理剛剛讀取的數據並將其連接到full_text。然後它回到循環條件,它再次調用read()read()塊,因爲此時沒有別的東西要從套接字讀取。
  4. 客戶端進入一個類似的循環,它試圖從套接字讀取,期望從服務器發送消息。
  5. 在這一點上,服務器和客戶端都被阻塞,等待彼此的消息,這將永遠不會發生。

塗換另一種方式:你只寫了一次套接字,不知何故,你期望多讀幾次。

你必須重新考慮你的設計。回到問題描述,通過一個簡單的協議工作,在紙上幹運行,然後實現它 - 這是它在現實世界中的完成:)

1

您的代碼中還有其他錯誤。例如,你寫這個:

strcat(full_text, buffer); 

buffer不是NUL終止。n字節已被讀取,其餘的緩衝區是不確定的。你應該偏移n設置'\0'字節,僅供試閱BUF_MAX-1字節保持字節適用於所有案件,做到這一點:

buffer[n] = '\0'; 
strcat(full_text, buffer); 

此外,如果有足夠的空間提供full_text的你不試n+1字節strcat將在最後複製。

另一方面,當服務器收到數據包時,數據包可以被分割成不同大小的塊。需要緩衝來確保可靠的客戶端/服務器通信。要啓用此緩衝,您需要設計一個協議來確定數據包何時完全接收:一個簡單的協議是傳輸由'\n'終止的行。