2013-11-28 4 views
4

기다립니다 http://www.mathworks.com/help/instrument/using-tcpip-server-sockets.htmlmatlab에 소켓 내가 MATLAB에서 다음과 같은 클라이언트 및 서버 소켓 예제 코드를 실행하기 위해 노력하고있어 응답

이 내 코드입니다.

서버 :

t=tcpip('0.0.0.0', 9994, 'NetworkRole', 'server'); 
fopen(t); 
data=fread(t, t.BytesAvailable, 'double'); 
plot(data); 

클라이언트 : 나는> 프로그램은 클라이언트 -로부터의 연결을 대기가> 나는 클라이언트 코드를 실행 코드 - 서버를 실행

data=sin(1:64); 
t=tcpip('localhost', 9994, 'NetworkRole', 'client'); 
fopen(t); 
fwrite(t, data, 'double'); 

이 일어나는 것이다 -> 서버 콘솔에서 다음과 같이 표시됩니다.

Error using icinterface/fread (line 163) 
SIZE must be greater than 0. 

Error in socketTentativaMatlab (line 3) 
data=fread(t, t.BytesAvailable, 'double'); 

무엇이 잘못 되었나요? 서버가 클라이언트가 데이터를 읽으려고 보내기 위해 아무 것도 보내지 않을 때까지 기다릴 필요가 없으므로 읽을 데이터가 없습니다 (클라이언트 연결 생각을 기다립니다).


EDIT1 : 좋아, 지금은 문자를 보내고있다, 그래서 우리는 확실히 알고 t.BytesAvaiable = 요소의 수.

나는 성공적으로 (이, 클라이언트 코드가 같은 서버 코드입니다하지만 지금 문자를 전송하고 서버와의 연결 설정 후 1 초 일시 정지) 다음과 같은 방법으로 동 기적으로받을 수 있었다 :

t=tcpip('0.0.0.0', 30000, 'NetworkRole', 'server'); 
fopen(t); 
data=strcat(fread(t, 1, 'uint8')'); 
if get(t,'BytesAvailable') > 1 
    data=strcat(data,fread(t, t.BytesAvailable, 'uint8')'); 
end 
data 

bytesAvaiable은 적어도 한 번 읽으려고 시도한 후에 읽어야 할 바이트 수입니다 ... 이것은 매우 논리적으로 보이지 않지만 분명히 발생합니다. 메시지가 몇 바이트인지를 알기 위해서는 적어도 한 번 읽어야하므로 처음에는 1 바이트 만 읽도록 선택합니다. 그런 다음 남은 것을 읽었습니다. 왼쪽에있는 것이 있으면 ...

이 작업은 matlab 프로세스간에 만들 수 있지만 C++과 matlab 간에는 할 수 없습니다. C++ 클라이언트가 성공적으로 matlab 서버에 연결하고 문제 또는 오류없이 데이터를 보낼 수 있습니다. 그러나, matlab에 서버 쪽, 나는 그것을 읽을 수 없습니다.

이 모든 MATLAB tcpip 구현에 문제가있는 것처럼 보입니다!


Edit2가 : 내가 제대로 클라이언트와 서버 (기본적으로 열려있는 소켓 프로그램 종료를하지 않는) 모두에서 모든 소켓을 닫으면은, 위의 코드 솔기가 지속적으로 작동하는 . 나는 콘솔에 가서 "netstat"을 타이프하여 모든 연결을 보았습니다 ... 오픈 소켓을 남겨 두었 기 때문에 어떤 연결은 FIN_WAIT_2 상태에 있었고 분명히이 연결의 포트를 사용할 수 없게 만들었습니다. 결국 연결 시간은 확실히 정해 지지만 1 분 이상 소요되므로 소켓이 항상 올바르게 닫혀 있는지 확인하는 것이 가장 좋습니다.

나는 t.BytesAvaiable의 뒤에있는 논리가 무엇인지 생각하지 못합니다 ... 그것이 그 방법을 많이 이해할 수 있도록 솔기가 없습니다. 루프를 실행 한 후 0이 될 때까지 기다리면 결국 발생하지만 동기식 소켓을 사용하는 것이 아닙니다. 필자는 t.BytesAvaiable이 처음 제대로 설정되지 않은 이유를 알지 못한다고하더라도 내 코드를 사용하면 동기식으로 작업을 수행 할 수 있습니다.

최종 서버 코드 :

t=tcpip('0.0.0.0', 30000, 'NetworkRole', 'server'); 
fopen(t); 

data=strcat(fread(t, 1, 'uint8')); 
if get(t,'BytesAvailable') > 1 
    data=strcat(data,fread(t, t.BytesAvailable, 'uint8')'); 
end 

fclose(t); 

최종 클라이언트 코드 : 어떤 언어로 구현

전형적인 소켓 클라이언트,하지만 당신은 확인해야합니다 그 전송의 연속 통화 사이의() 메소드/함수 호출 (또는 connect()와 send() 호출 사이), 최소 100ms (위험한 이음새 번호가 작음)가 생략됩니다.

+0

클라이언트가 시작되지 않은 경우,'t.BytesAvailable'은 0이고 당신은 0 바이트를 읽습니다. 이것은 불가능합니다.'t.BytesAvailable> 0' – Daniel

+0

인 경우에만 읽을 수 있습니다. @DanielR 링크가 잘못되어 @DanielR이 내 질문을 편집했습니다. 이제는 맞습니다. 당신의 대답에 대해, 나는 당신이 의미하는 것을 이해하지 못합니다. fopen은 클라이언트가 연결될 때까지 기다린다. 그래서 문제가 있어서는 안된다 ... 처음부터 활성화되어있는 서버이다 ... – jmacedo

+1

@joxnas, 나는 BytesAvailable이 단지 후에 설정되었다고 생각하지 않는다. 읽으려는 시도. 왜냐하면 나는 단순히 기다리는 것으로 작업을했기 때문이다. 바이트를 읽은 후 더 잘 작동하는 또 다른 이유가 있을지 모르겠습니다. 나는 동의한다, 구현은 상당히 진절머리 나는 것처럼 보인다. 가능한 해결책 : Matlab과 함께 제공되는 java를 사용하십시오. 그것은 오래되었지만 java.ui의 ServerSocket과 Socket을 사용하여 Java에서 간단한 웹 서버를 구현하는 데 문제가 없었습니다. –

답변

6

통신의 기본 모드가 동기식이라 할지라도 서버가 클라이언트를 기다리지 않는 것으로 보입니다. 예를 들어

while t.BytesAvailable == 0 
    pause(1) 
end 

을 삽입하여 대기 상태를 구현할 수 있습니다.

그러나 더 많은 문제가 있음을 발견했습니다. 매스 웍스 사이트의 코드가 매우 나쁘다는 것을 알게되었습니다. 즉, t.BytesAvailable은 많은 바이트를 제공하는 반면, fread은 여러 값을 기대합니다. 값은 클라이언트가 즉시 연결을 연 후, 나는 서버가 단순히 그들을 내려다 것으로 나타났습니다 데이터를 기록하는 경우, 또한

data=fread(t, floor(t.BytesAvailable/8), 'double'); 

말을하는 8 바이트가 필요합니다. 나는 ...

data=sin(1:64); 
t=tcpip('localhost', 9994, 'NetworkRole', 'client'); 
fopen(t); 
pause(1) 
fwrite(t, data, 'double'); 

내 인상은 TCP/IP 서버 클라이언트 통신의 matlab에 구현이 매우 취약하다는 것이다 및 해결 방법을 많이 필요로 같은 클라이언트 코드에 pause(1)를 삽입하여이 문제를 해결할 수 있었다

+0

제 질문을 편집했습니다. 제발! – jmacedo

관련 문제