C 中的 CR/LF 条件检查

发布于 2024-11-05 23:10:38 字数 672 浏览 0 评论 0原文

我正在使用 Telnet 测试我的 TCP 回显服务器,我可以看到客户端连接到服务器并发送一个字符,作为回报,服务器返回一个字符串给客户端。

现在我的问题是通过在无限循环中使用这个rec​​v()我只能接收一个字符(即使客户端倾向于发送一个字符串)。

接收数据报的方式。

这就是我从客户端TCP 服务器

while(1)
{
    socket = accept(server_socket, (struct sockaddr *)&client_address, (socklen_t)&client_length);

    recv(socket, recv_buffer, sizeof(recv_buffer), 0);
    printf("Received string from client is %s", recv_buffer);

    /*then I send my string to the client*/
    send(socket, send_buffer, sizeof(send_buffer), 0);
}

这是我的问题,即使客户端想要发送整个字符串,我的 recv() 例程也只读取一个字符。有没有办法让这个 recv() 例程在接收来自客户端的所有字符之前等待,然后向客户端发送响应。

任何建议将不胜

感激

I am testing my TCP echo server, with Telnet, I can see that the client connects to the server and sends a charcter and in return the server returns a string to the client.

Now my problem is by using this recv() in a infinite loop I can only receive one character (even though the client tends to send a string).

This is how I am doing to receive the datagram from the client

TCP SERVER

while(1)
{
    socket = accept(server_socket, (struct sockaddr *)&client_address, (socklen_t)&client_length);

    recv(socket, recv_buffer, sizeof(recv_buffer), 0);
    printf("Received string from client is %s", recv_buffer);

    /*then I send my string to the client*/
    send(socket, send_buffer, sizeof(send_buffer), 0);
}

Here is my problem that my recv() routine reads only one character even though the client wants to send a whole string. Is there a way how I can make this recv() routine wait before it receives all the characters from the client and then send a response to the client.

Any suggestions would be appreciated

Regards

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

青柠芒果 2024-11-12 23:10:38

好吧,你做错了什么。看一下 recv 的定义:

int recv(int s, void *buf, size_t len, int flags); 

它接收 len 字节数。您将 sizeof(recv_buffer) 作为 len 参数传递。现在我猜测 recv_buffer 被定义为 char*。获取指针的 sizeof 意味着您获得存储该指针所需的字节数,而不是它指向的内存。

做这样的事情:

const int buf_len = 100;
char recv_buffer[buf_len];

recv(socket, recv_buffer, buf_len, 0);
printf("Received string from client is %s", recv_buffer);   

Well, you are doing something wrong. Look at the definition of recv:

int recv(int s, void *buf, size_t len, int flags); 

So it recieves len amount of bytes. You passed sizeof(recv_buffer) as the len parameter. Now I'm guessing recv_buffer is defined as a char*. Getting the sizeof of a pointer means that you get the amount of bytes necessary to store that pointer, instead of the memory it points to.

Do something like this instead:

const int buf_len = 100;
char recv_buffer[buf_len];

recv(socket, recv_buffer, buf_len, 0);
printf("Received string from client is %s", recv_buffer);   
忆沫 2024-11-12 23:10:38

您需要在循环中构建您自己接收的字符串,使用 recv() 的返回值来查找您实际获得的字节数。 TCP/IP 不保证一次调用 send() 发送的所有数据都可以通过一次调用 recv() 接收。并且您必须检查您调用的每个套接字函数的返回值,以检查发送/接收的实际长度以及错误。

You need to build up the string you are receiving yourself in a loop, using the return value of recv() to find how many bytes you actually got. TCP/IP does not guarantee that all the data sent with one call to send() can be received with one call to recv(). And you must examine the return value of every sockets function you call to check for actual lengths sent/received, and for errors.

坏尐絯℡ 2024-11-12 23:10:38

你的代码是一场灾难(很抱歉直言不讳,但最好是直截了当)。

recv() 返回实际读取的字节数。不仅如此,它不会清除缓冲区以前的内容,如果有可用数据,它会一直填满缓冲区的末尾。所有这些意味着您不能将缓冲区的内容视为以空结尾的字符串。

你需要做类似的事情:

ssize_t bytesRead = 1;
char recv_buffer[SOME_SIZE];

while (bytesRead > 0)
{
    int bytesRead = recv(socket, recv_buffer, SOME_SIZE, 0);
    if (bytesRead > 0)
    {
        // do something with the bytes.  Note you cannot guarantee that the buffer contains a valid C string.
    }    
}
if (bytesRead == -1)
{
    // report error from errno
}
else
{
    // bytesRead == 0 have reached end of file (i.e. socket closed at other end)
}

没有办法让recv等到缓冲区已满后再返回。它将等待,直到有一些可用字节,然后返回。顺便发送也是如此。您不能通过一次调用来假设所有字节实际上都已发送。您还需要将 send 放入循环中:

ssize_t totalBytesWritten = 0;
ssize_t bytesWritten = 0;
while (bytesWritten >= 0 && totalBytesWritten < bytesToWrite)
{
    bytesWritten = send(socket, sendBuffer + totalBytesWritten, bytesToWrite - totalBytesWritten, 0);
    if (bytesWritten > 0)
    {
        totalBytesWritten += bytesWritten;
    }
}
if (bytesWritten == -1)
{
    // error
}

Your code is a disaster (sorry for being blunt, but it is best to be straight).

recv() returns the number of bytes actually read. Not only that but it will not clear the previous contents of the buffer and it will fill up right to the the end of the buffer if there is data available. All this means that you cannot treat the content of the buffer as a null terminated string.

You need to do something like:

ssize_t bytesRead = 1;
char recv_buffer[SOME_SIZE];

while (bytesRead > 0)
{
    int bytesRead = recv(socket, recv_buffer, SOME_SIZE, 0);
    if (bytesRead > 0)
    {
        // do something with the bytes.  Note you cannot guarantee that the buffer contains a valid C string.
    }    
}
if (bytesRead == -1)
{
    // report error from errno
}
else
{
    // bytesRead == 0 have reached end of file (i.e. socket closed at other end)
}

There is no way to get recv to wait until the buffer is full before returning. It will wait until there are some bytes available and then return. The same applies to send by the way. You can't assume with one call to send that all of your bytes have actually been sent. You need to put send in a loop too:

ssize_t totalBytesWritten = 0;
ssize_t bytesWritten = 0;
while (bytesWritten >= 0 && totalBytesWritten < bytesToWrite)
{
    bytesWritten = send(socket, sendBuffer + totalBytesWritten, bytesToWrite - totalBytesWritten, 0);
    if (bytesWritten > 0)
    {
        totalBytesWritten += bytesWritten;
    }
}
if (bytesWritten == -1)
{
    // error
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文