我正在尝试在Matlab中运行以下客户端和服务器套接字示例代码:
http://www.mathworks.com/help/instrument/using-tcpip-server-sockets.html
这是我的代码。
服务器:
客户:
这是发生的事情:我运行服务器代码 -> 程序等待客户端连接 -> 我运行客户端代码 -> 在服务器控制台上,我得到:
我做错了什么?看起来服务器没有等待客户端发送任何内容就尝试读取数据,因此没有数据可读(它等待客户端连接)。现在我正在发送字符,所以我们确定 t.BytesAvailable = 元素数量。我已成功地以同步方式接收到以下方式的信息(这是服务器代码,客户端代码相同,但现在我发送字符并在与服务器建立连接后暂停1秒):
这是因为我怀疑bytesAvaiable是在尝试读取至少一次后剩余要读取的字节数...这似乎不太合理,但显然就是这样。由于我必须至少读取一次才能知道消息有多少字节...我选择第一次只读取1个字节。然后如果还有剩余的话,再读取剩下的部分...
我可以让这个在Matlab进程之间工作,但我无法在C++和Matlab之间做到这一点。C++客户端成功连接到Matlab服务器,并可以发送数据而没有问题或错误。然而,在Matlab服务器端,我无法读取它。
所有这些Matlab tcpip实现似乎都有很大问题!
编辑2: 如果我正确关闭客户端和服务器中的所有套接字(基本上不让程序退出时保持打开状态),上面的代码似乎可以始终正常工作。我去控制台并输入“netstat”以查看所有连接...结果由于我留下了打开的套接字,一些连接处于FIN_WAIT_2状态,这显然使得这些连接的端口无法使用。最终连接会超时,但需要一分钟或更长时间,因此,最好的做法是确保套接字始终正确关闭。
我不明白t.BytesAvaiable背后的逻辑...它似乎没有正确设置。如果我循环并等待它变得大于0,最终会发生这种情况,但这不是同步套接字的预期方式。我的代码允许以同步方式执行操作,即使我不理解为什么t.BytesAvaiable第一次没有正确设置。
最终服务器代码:
最终客户端代码:
这是一个典型的套接字客户端,可以使用任何编程语言实现,但你必须确保在连续调用send()方法/函数(或在调用connect()和send()之间),至少要经过100毫秒的时间(较低的数字似乎存在风险)。
服务器:
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');
我做错了什么?看起来服务器没有等待客户端发送任何内容就尝试读取数据,因此没有数据可读(它等待客户端连接)。现在我正在发送字符,所以我们确定 t.BytesAvailable = 元素数量。我已成功地以同步方式接收到以下方式的信息(这是服务器代码,客户端代码相同,但现在我发送字符并在与服务器建立连接后暂停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实现似乎都有很大问题!
编辑2: 如果我正确关闭客户端和服务器中的所有套接字(基本上不让程序退出时保持打开状态),上面的代码似乎可以始终正常工作。我去控制台并输入“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()之间),至少要经过100毫秒的时间(较低的数字似乎存在风险)。
s = java.net.Socket()
会给你一个Socket对象。 - A. Donda