我正在编写一个简单的客户端,它通过 TCP 流读取二进制数据。由于文件是逐部分发送的,因此我有一个与此类似的循环:
while (1 /* Maybe a check for EOF or if the socket is closed here ? */) {
ssize_t bytes_red = recv(
if (bytes_read <= 0) // not working properly ?
break;
...
}
Run Code Online (Sandbox Code Playgroud)
读取是通过 recv() 方法完成的,该方法返回接收到的字节数。这个想法显然是只要打开 TCP 流就读取数据,但似乎上述方法对我不起作用。
还有其他想法吗?从套接字读取直到流关闭或遇到 EOF 的干净方法是什么?
编辑:上述方法工作正常,我在其他地方有一个错误。
不确定这是TCPClient还是别的什么,我使用网络嗅探器检查从服务器发送和接收的内容,数据是否正确,但我的软件接收数据不正确.
让我解释一下,我发送一个查询字节(05)我得到一个确认回(06)然后我发送一些以9B字节开头的数据,一旦发送,我应该接收一个06字节,然后在那个字节之后我应该得到一个C5字节,但根据我的软件我得到另一个06字节,根据嗅探器不是这种情况!
byte[] buff;
if (!this.isConnected())
this.connect();
NetworkStream gs = _Socket.GetStream();
gs.Write(enq, 0, enq.Length);
gs.Flush();
outputByte(enq, "Trans"); //outputs ---> 05
buff = new byte[1];
gs.Read(buff, 0, buff.Length);
gs.Flush();
outputByte(buff, "Rec");// outputs <--- 06
if (buff[0] == 0x06)
{
byte[] data = new byte[] {
0x9B, 0x00, 0x80, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x09,
0x67, 0x11, 0x01, 0x49, 0x4D, 0x41, 0x47, 0x45, 0x31, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x53, …Run Code Online (Sandbox Code Playgroud) 我尝试在idtcpclient中接收文本,但它不起作用.这是我在计时器中使用的代码:
procedure TForm1.Timer2Timer(Sender: TObject);
var
receivedtext:string;
begin
if idtcpclient1.Connected = true then
begin
with idtcpclient1 do
begin
if not IOHandler.InputBufferIsEmpty then
begin
try
receivedtext := IOHandler.ReadLn;
finally
if receivedtext = '' = false then
begin
showmessage(receivedtext);
idtcpclient1.IOHandler.InputBuffer.Clear;
receivedtext := '';
end;
end;
end;
end;
end
else
begin
timer2.Enabled := false;
end;
end;
Run Code Online (Sandbox Code Playgroud)
定时器的间隔为8 ms.计时器在连接时自动启用.但是当我发送内容时,我没有收到消息框或错误.我确信我写的数据是因为当我使用时,tclientsocket我会收到它.
我做错了什么?
我试图让客户端向我的服务发送命令,该命令为"R".但是当我尝试制作一个IF语句时,它不会将通过TCP输入的"R"注册为等于我在程序中创建的字符串R. 这是我的一些代码.
byte[] message = new byte[1024];
byte[] command = Encoding.ASCII.GetBytes("R");
stream.Read(message, 0, message.Length);
string messageIn = Encoding.ASCII.GetString(message);
//updateUI("New Message = " + messageIn);
string commandString = Encoding.ASCII.GetString(command);
if (Encoding.ASCII.GetString(message) == Encoding.ASCII.GetString(command))
Run Code Online (Sandbox Code Playgroud)
正如你所看到的,我的印象是将"R"转换为字节然后超出字节会导致这个问题因此成为巨大的if语句.但是,由于我的if块从不运行,因此这些条件中没有一个返回true.
我知道它正在返回"R",因为当我将它输出到文本框时,这就是打印的内容.转移它的行为是通过tcp以某种方式改变字符串吗?
我正在尝试验证网站是否已启动。我正在使用 TcpClient 调用网站并且它工作正常但是当我对同一站点使用 webrequest 时它会引发 404 错误。
TcpClient 和 webRequest 的功能有什么区别??
var client = new TcpClient();
client.Connect("android.clients.google.com", 80);
var request = WebRequest.Create("http://android.clients.google.com");
var resp = request.GetResponse();
Run Code Online (Sandbox Code Playgroud) 我有一个带有16个继电器的电子板,它可以通过TCP / IP进行工作。主板的IP地址是192.168.1.4,端口是3000。我想在Ubuntu下用C / C ++对其进行控制。
可以使用十六进制命令列表来远程打开和关闭板上的每个继电器。这是清单:
"580112000000016C", // switch on the relay 1
"580111000000016B", // switch off the relay 1
"580112000000026D", // switch on the relay 2
"580111000000026C", // switch off the relay 2
"580112000000036E", // and so on..
Run Code Online (Sandbox Code Playgroud)
我可以通过在Ubuntu下发送命令行命令来正确地打开和关闭每个中继:
echo '580112000000016C' | xxd -r -p | nc 192.168.1.4 3000
Run Code Online (Sandbox Code Playgroud)
上面的代码正确打开了继电器。
我想对C / C ++代码做同样的事情,因为我想从WxWidgets应用程序控制开发板。目前,我是从基础开始的,我只是使用C / C ++代码来测试tcp连接。
这是我的代码:
#include <stdio.h>
#include <errno.h>
#include <string.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <cstring>
#include <string>
#include <unistd.h>
using namespace std;
int …Run Code Online (Sandbox Code Playgroud)