2009-12-11 34 views
8

Chức năng recv của tôi bị treo trong khi nhận phản hồi từ máy chủ.Lập trình Socket C/C++ - chức năng recv bị treo?

Khách hàng mã phía trong c/C++:

void sockStuff() { 

int sock, bytes_recieved,bytes_send; 
char send_data[1024], recv_data[4096]; 

struct hostent *host; 
struct sockaddr_in server_addr; 

host = gethostbyname("127.0.0.1"); 

if ((sock = socket(AF_INET, SOCK_STREAM, 0)) == -1) { 
    perror("SocketError"); 
    exit(1); 
} 
server_addr.sin_family = AF_INET; 
server_addr.sin_port = htons(50500); 
server_addr.sin_addr = *((struct in_addr *) host->h_addr); 
bzero(&(server_addr.sin_zero), 8); 


if (connect(sock, (struct sockaddr *) &server_addr, sizeof(struct sockaddr)) 
    == -1) { 
    perror("ConnectToError"); 
    exit(1); 
} 


    bytes_send = send(sock, a, strlen(a), 0); 
    bytes_send = shutdown(sock, 1); 


bytes_recieved = recv(sock, recv_data, 4096, 0); //Where the program hangs?? 
recv_data[bytes_recieved] = '\0'; 
printf("\nRecieved data = %s ", recv_data); 
cout << endl << endl; 

shutdown(sock,2); 



} 

Khách hàng của tôi là C bên/C++ và máy chủ là OpenEdge Progress. Vui lòng xem mã và đề xuất những gì đã xảy ra với vấn đề này. ??

+0

Bạn nên sử dụng sizeof (server_addr.sin_zero) thay vì số ma thuật 8. Hoặc tốt hơn vẫn không phải toàn bộ cấu trúc và sau đó thiết lập các trường bạn quan tâm. –

+0

Xin chào Neil, bạn có thể vui lòng giải thích điều này hơn khi tôi thử sizeof (server_addr.sin_zero) thay vì số 8 nhưng vẫn không có may mắn.Thnx. – Vishal

Trả lời

1

recv nên treo cho đến khi bạn nhận được phản hồi từ máy chủ, bạn có cho biết rằng phản hồi đang được gửi hay không.
Thử dùng công cụ đánh dấu hoặc một cái gì đó tương tự để đánh hơi mạng và xem phản ứng thực tế có đến hay không.

+0

Trên thực tế sau khi recv() treo cứng, tôi đã thử ctrl + alt + del.By thực hiện công việc quản lý này mở nhưng tôi đóng trình quản lý tác vụ này (không bị giết bất kỳ quá trình nào) và đột nhiên nó mang lại cho tôi phản hồi một lần.Nhưng chương trình của tôi vẫn ở trạng thái đóng băng . – Vishal

1

Ummm .... tại sao bạn tắt máy tính, ổ cắm ....

 
bytes_send = send(sock, a, strlen(a), 0); 
    bytes_send = shutdown(sock, 1); /*** That I think is the problem! ***/ 


bytes_recieved = recv(sock, recv_data, 4096, 0); 

Tuy nhiên bạn vẫn tiếp tục trong các mã nhận được từ các ổ cắm cùng đó là tắt máy ??

Hy vọng điều này gợi ý bạn đi đúng hướng, Trân trọng, Tom.

+0

Thnx. Tom để trả lời. Nhưng tắt máy (vớ, 1); không phải là đóng socket.It chỉ nói rằng gửi là không được phép (không có gì nhiều hơn để gửi.) Ngay cả khi tôi loại bỏ dòng này, recv của tôi() treo cứng. – Vishal

+0

@Vishal: Ok ... http: //www.developerweb.net/forum/showthread.php? T = 2940 - có một abotu thảo luận thú vị khi sử dụng tắt máy .. Mã đang ở chế độ đồng bộ, có thể là có thể rằng việc nhận dữ liệu đã xảy ra trước khi tắt máy và do đó treo. Bạn đã nghĩ về điều đó ...? Xin lỗi nếu tôi không có nhiều trợ giúp ở đây ... :( – t0mm13b

1

Recv sẽ chặn cho đến khi socket có thông tin để đọc miễn là socket ở chế độ chặn, bạn có thể thay đổi điều này bằng fcntl. Nếu bạn đang tự hỏi tại sao nó treo, tôi đoán là khi bạn tắt ống ghi trên ổ cắm (cũng có thể bạn muốn sử dụng SHUT_WR liên tục vì nó tốt hơn) máy chủ nhận EOF và giả định bạn đang ngắt kết nối, mặc dù điều đó có thể không đúng nếu máy chủ được thiết lập để xử lý nó.

Tôi khuyên bạn nên xem xét việc đặt ổ cắm thành chế độ không chặn, sau đó gọi select sẽ chặn cho đến khi ổ cắm có thể đọc/ghi/hoặc thời gian chờ được kích hoạt. Tùy thuộc vào những gì bạn đang làm, điều đó sẽ tạo nên sự khác biệt.

1

Thử sử dụng chế độ Không chặn. tức là recv sẽ trả về nếu không có dữ liệu nào để đọc, vì vậy hãy xử lý trường hợp này (trong một vòng lặp while hoặc với lựa chọn. tùy bạn)

Để biết thêm về recv, giả sử bạn đang sử dụng hệ thống POSIX) đọc số này http://www.opengroup.org/onlinepubs/009695399/functions/recv.html

8

Mã của bạn sẽ chặn cuộc gọi recv cho đến khi máy chủ gửi lại bất kỳ dữ liệu nào. Vì điều đó không xảy ra, có lẽ bạn nên tự hỏi liệu khách hàng của bạn có gửi yêu cầu hoàn chỉnh hay không. Máy chủ có thể sẽ không bắt đầu gửi phản hồi cho đến khi nhận được yêu cầu hoàn chỉnh.

Nếu giao thức máy khách/máy chủ của bạn dựa trên văn bản, như HTTP hoặc SMTP, bạn có chắc chắn phản hồi của bạn được chấm dứt chính xác không? Máy chủ có thể mong đợi CR + LF ('\ r \ n') thay vì chỉ LF ('\ n') hoặc dự kiến ​​một dòng trống để chấm dứt yêu cầu:

char *request = "GET /index.html HTTP/1.1\r\nHost: www.example.com\r\n\r\n"; 

PS. Bạn không khai báo hoặc khởi tạo 'a' trong đoạn mã của mình.

4

Mã của bạn sẽ chặn trong cuộc gọi recv cho đến khi máy chủ gửi lại mọi dữ liệu. Vì điều đó không xảy ra, có lẽ bạn nên tự hỏi liệu khách hàng của bạn có gửi yêu cầu hoàn chỉnh hay không. Máy chủ có thể sẽ không bắt đầu gửi phản hồi cho đến khi nhận được yêu cầu hoàn chỉnh.

Nếu giao thức máy khách/máy chủ của bạn dựa trên văn bản, như HTTP hoặc SMTP, bạn có chắc chắn phản hồi của bạn được chấm dứt chính xác không? Máy chủ có thể mong CR + LF ('\ r \ n') thay vì chỉ LF ('\ n') hoặc nó dự kiến ​​một dòng trống để chấm dứt yêu cầu:

char * request = "GET/index. html HTTP/1.1 \ r \ nMáy chủ: www.example.com \ r \ n \ r \ n "; PS. Bạn không khai báo hoặc khởi tạo 'a' trong đoạn mã của mình. "Bởi notacat

Tôi đã làm việc trên bản sao của mình về chiến thắng đầu tiên 1.0 và 1.1 thực hiện bằng c + + khi giành chiến thắng Mã của tôi đã hoạt động tất cả các cách để recv () gọi, và sau đó chỉ cần treo ở đó ... Tôi biết về ngăn chặn \ Không chặn ổ cắm, nhưng đó không phải là giải pháp tôi yêu cầu.Từ khi tôi thấy yêu cầu của tôi trong wireshark hoặc tương tự tôi biết rằng máy chủ đã nhận được yêu cầu kết thúc chuỗi của tôi trên cổng 80, và mã của tôi đóng băng trên recv() gọi do không giao tiếp giữa khách hàng và máy chủ của tôi trên 'net. Điều đó dẫn tôi đến tin rằng tôi đã không gửi yêu cầu thích hợp. Tốt, tác giả (notaket) đã được tại chỗ trên! Ngay sau khi tôi thay đổi yêu cầu của anh ta ("GET /index.html HTTP/1.1 \ r \ n \ n \ n \ n" \ n "" \ n "" \ n "" \ n ""), tất cả dường như hoạt động như một sự quyến rũ !. !!

Các vấn đề liên quan