通过TCP套接字发送不全字符缓冲区 [英] Sending char buffer through TCP socket incomplete

查看:147
本文介绍了通过TCP套接字发送不全字符缓冲区的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我只是在学习如何处理C.套接字和TCP连接我有一个应用程序(一个漫长的)基本上发送,并与系统调用write接收字符数组从服务器到客户端,反之亦然(二当然,单独的C应用程序)。只要我用它与本地连接,在同一台PC上运行的终端服务器,并上另一个客户端,一切都只是正常工作,并在目的地的数据到达。但是,如果我尝试用一​​台计算机上的服务器,而在另一个但同样的互联网线上客户端,传递到客户端类似192.168.1.X的地址(从了服务器在其上运行的机器),后建立连接后,我已经得到了告诉我,预计字节数(我发送真正的char []前通过)没有到达一个错误。如果我尝试在一个又一个与不同的供应商不同的线路我的电脑在服务器,客户端同样的事情。

I'm just learning how to handle sockets and TCP connections in C. I've got an application (a long one) which basically sends and receives char arrays with the system call write from server to client and vice versa (two separate C applications of course). As long as I use it with a local connection, on the same PC, running the server on a terminal and the client on an another, everything just works fine and the data arrives at the destination. But if I try it with the server on one computer and the client on another but on the same internet line, passing to the client an address like 192.168.1.X (took from the machine on which the server is running), after the connection is established, I've got an error that tells me that the number of expected bytes (which I pass before sending the real char[]) isn't arrived. Same thing if I try the server on my PC, and the client on another one with a different line on a different provider.

有我丢失的东西,有没有按顺序发送一串字节任何限制?

There's something I'm missing, are there any limitations in sending a bunch of bytes in sequence?

在code,其中的错误弹出。

The code where the error pops up.

服务器端:

r=htonl(lghstr);
w=write(myFd,&r,sizeof(int));//writes the number of incoming bytes
if(w<0) perror("writeServer4"),exit(-1);
w=write(myFd,tmp->string,lghstr);
if(w<0) perror("writeServer5"),exit(-1);
if(w!=lghstr) perror("ERROR");

客户端

rC=read(fdc,&cod,sizeof(int));//read incoming number of bytes
lghstr=ntohl(cod);
if(rC<0) perror("readClient3"),exit(-1);
rC=read(fdc,dest,lghstr);
if(rC<0) perror("readClient4"),exit(-1);
if(rC!=lghstr) perror("error : "), printf("didn't read the right number of bytes"),exit(-1);

现在这基本上是重复了很多次,我们甚至可以说300次,并将其与大数字,该程序不能正常工作的。

Now this is basically repeated a lot of times, let's even say 300 times, and it's with big numbers that the program doesn't work.

推荐答案

这就是问题所在:

rC=read(fdc,dest,lghstr);
...
if(rC!=lghstr) perror("error : ")

#1谬论套接字编程期待的的recv()阅读()将返回这里相同数量的对应于由另一侧作出的写/发送调用字节

The #1 fallacy with socket programming is expecting that recv() and read() will return exactly the same number of bytes corresponding to the write/send call made by the other side.

在现实中,部分数据是极有可能和预期。最简单的解决方法是在读取循环/ recv的,直到你得到预期的字节的确切数字:

In reality, partial data is extremely likely and expected. The simple workaround is to loop on read/recv until you get the exact number of bytes expected:

size_t count = 0;
while (count < lghstr)
{
    ssize_t readresult = read(fdc, dest+count, lghstr-count);
    if (readresult == -1)
    {
      // socket error - handle appropriately (typically, just close the connection)
    }
    else if (readresult == 0)
    {
      // The other side closed the connection - handle appropriately (close the connection)
    }
   else
    {
        count += readresult;
    }
}

其他的替代循环是利用与插座的MSG_WAITALL标志。这意味着,使用的recv(),而不是阅读()。您仍然需要处理错误的案件。

The other alternative to looping is to the use the MSG_WAITALL flag with the socket. This means, using recv() instead of read(). You'll still need to handle the error cases.

rc = recv(fdc, dest, lghstr, MSG_WAITALL);
if (rc == -1)
{
  // socket error
}
else if (rc == 0)
{
  // socket closed by remote
}
else if (rc < lghstr)
{
   // the other side likely closed the connection and this is residual data (next recv will return 0)
}

这篇关于通过TCP套接字发送不全字符缓冲区的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆