2014-02-11 4 views
0

좋은 하루.C++ : 서버와 클라이언트 간의 클래식 통신 연습

로우 레벨 C 프로그래밍을 배우는 컴퓨터 과학 학생으로서 나는 서버 - 클라이언트 통신 프로그램을 작성하는 "고전적인"연습 연습에 빠져 있습니다.

목표는 원격 클라이언트 구성 요소에서 명령을 받고 로컬 쉘 명령으로 실행하는 서버 구성 요소를 개발하는 것입니다. 그런 다음 명령의 출력이 클라이언트로 다시 전송됩니다. 아주 간단합니다.

내 코드는 클라이언트에서 명령을 보내고 서버가 성공적으로 명령을 수신하여 실행하고 출력을 캡처합니다. 그러나이 시점에서 sayd 서버가 클라이언트에게 출력물을 보내려고 할 때 ... 뭔가 잘못되어 클라이언트가 아무것도받지 못합니다. 문제가 서버 파트 또는 클라이언트 파트에있는 경우 단서 없음.

아이디어가 있으십니까? 미리 감사드립니다!

서버 :

struct sockaddr_in srvaddr, cliaddr; 
memset(&srvaddr, 0, sizeof(srvaddr)); 
memset(&cliaddr, 0, sizeof(cliaddr)); 

int sk = socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP); 

srvaddr.sin_family = AF_INET; 
srvaddr.sin_addr.s_addr = inet_addr("127.0.0.1"); 
srvaddr.sin_port = htons(42000); 
bind(sk, (struct sockaddr*)&srvaddr, sizeof(srvaddr)); 
recvfrom(sk, recepcion, sizeof(recepcion), 0, (struct sockaddr*)&cliaddr, sizeof(cliaddr)); 

// [...] Portion of code with a Pipe pointing to a Fork which runs the command... 

// And here is where, maybe, the communication is lost: 
sendto(sk, recepcion, sizeof(recepcion), 0, (struct sockaddr*)&cliaddr, sizeof(cliaddr)); 

클라이언트 :

struct sockaddr_in srvaddr, cliaddr; 

memset(&srvaddr, 0, sizeof(srvaddr)); 
memset(&cliaddr, 0, sizeof(cliaddr)); 

int sk = socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP); 

cliaddr.sin_family = AF_INET; 
cliaddr.sin_addr.s_addr = inet_addr("127.0.0.1"); 
cliaddr.sin_port = htons(42001); 

srvaddr.sin_family = AF_INET; 
srvaddr.sin_addr.s_addr = inet_addr("127.0.0.1"); 
srvaddr.sin_port = htons(42000); 

// [...] Some other code catching the command from the argument paramenters: 

sendto(sk, comando, strlen(comando), 0, (struct sockaddr*)&srvaddr, sizeof(srvaddr)); 

// And here's where the server reply should be, but theres nothing: 
recvfrom(sk, buff, sizeof(buff), 0, (struct sockaddr*)&srvaddr, sizeof(srvaddr)); 

내가 가진 모든 흔적 인쇄 말 : 는 fprintf를 (표준 오류, ""); 따라서, 포크로 인해 터미널의 초점을 잃어 버려도 문제가되지 않습니다.

안녕히 주무세요!

답변

0

문제는 대부분 recvfrom 호출입니다. the manual page을 체크하면 소스 주소 길이가 포인터임을 알 수 있습니다. 오류나 경고없이 컴파일하는 방법을 알지 못합니다.

당신은 소켓 주소 구조의 실제 크기로 크기를 초기화해야

는, 그것에 대한 포인터를 전달하고, recvfrom 기능은 실제 크기를 입력합니다 :

socklen_t cliaddrlen = sizeof(cliaddr); 
recvfrom(sk, recepcion, sizeof(recepcion), 0, 
     (struct sockaddr *) &cliaddr, &cliaddrlen); 

아, 그리고 내가 할 실제 코드의 오류를 확인한다고 가정합니다.

관련 문제