我正在尝试在 matlab 中运行以下客户端和服务器套接字示例代码:http://www.mathworks.com/help/instrument/using-tcpip-server-sockets.html http://www.mathworks.com/help/instrument/using-tcpip-server-sockets.html
这是我的代码。
Server:
t=tcpip('0.0.0.0', 9994, 'NetworkRole', 'server');
fopen(t);
data=fread(t, t.BytesAvailable, 'double');
plot(data);
Client:
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 状态,这显然导致这些连接的端口不可用。最终连接肯定会超时,但需要一分钟或更长时间,因此,最好的做法是确保套接字始终正确关闭。
我不明白 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);
最终客户端代码:
您的典型套接字客户端可以用任何语言实现,但您必须确保在连续调用 send() 方法/函数之间(或调用 connect() 和 send() 之间)至少有 100ms(较低的数字接缝是有风险)已过去。