C 插座清洁
我对unix套接字(TCP本地)有点困惑 我有一个服务器和一个客户端:C 插座清洁,c,linux,sockets,ipc,C,Linux,Sockets,Ipc,我对unix套接字(TCP本地)有点困惑 我有一个服务器和一个客户端: 客户端通过套接字向服务器发送一些信息(使用发送) 多次 server打印此数据(server调用recv接收数据) 问题是,服务器不仅打印由客户端发送的最后一个信息,而且还打印来自该客户端的一些旧信息(有时已损坏),因此我认为套接字以某种方式累积了客户端写入它的所有以前的数据 服务器如何仅接收来自客户端的最后数据?我应该以某种方式清理套接字,还是应该一直关闭它并创建新的(非常糟糕的解决方案)?TCP套接字是流套接字。 这
- 客户端通过套接字向服务器发送一些信息(使用
) 多次发送
- server打印此数据(server调用
接收数据)recv
服务器如何仅接收来自客户端的最后数据?我应该以某种方式清理套接字,还是应该一直关闭它并创建新的(非常糟糕的解决方案)?TCP套接字是流套接字。
这意味着您发送的所有数据都不是作为消息序列处理的,而是作为字节序列处理的。字节按顺序接收,没有添加或删除,但不一定在相同的块中
例如,如果您的客户端调用
send
3次,每次调用1000字节,则无法判断recv
将返回多少次数据。它可能返回3次,每次1000字节,或者仅返回一次,每次返回3000字节,或者理论上甚至返回3000次,每次返回1字节。TCP套接字是流套接字。这意味着您发送的所有数据都不是作为消息序列处理的,而是作为字节序列处理的。字节按顺序接收,没有添加或删除,但不一定在相同的块中
例如,如果您的客户端调用
send
3次,每次调用1000字节,则无法判断recv
将返回多少次数据。它可能返回3次,每次1000字节,或者仅返回一次,每次返回3000字节,或者理论上甚至返回3000次,每次返回1字节。图像发送/接收的字节被放入队列(内部缓冲区)。如果调用send()
两次,每次发送10个字节,缓冲区中将有20个字节。当另一方调用recv()
时,它将从该队列中取出一些字节,并将它们放入传递的数组中。多少字节?最多可用(20)个或更少
例如,如果你打电话
nb = recv(socket, arr, 15,...);
然后只消耗15个字节(假定您的数组arr
具有此长度),它们将被复制到arr
,nb
将为15个字节,而在内部缓冲区中,我们只剩下5个字节
如果我们打电话
nb = recv(socket, arr, 100,...);
然后将20个字节复制到arr
,nb
将为20,内部缓冲区将为空
这表明:
send()
- 您必须始终检查
返回(recv
)以了解读取了多少字节nb
- 您无法知道在每个
调用中发送了哪些字节。“消息”的划分取决于您send()
- 您没有读取消息,也没有读取字符串(以null结尾的字符数组),您只是读取字节。然后,您不能只调用
来查看接收到的字节printf(“%s”,arr)
send()
两次,每次发送10个字节,缓冲区中将有20个字节。当另一方调用recv()
时,它将从该队列中取出一些字节,并将它们放入传递的数组中。多少字节?最多可用(20)个或更少
例如,如果你打电话
nb = recv(socket, arr, 15,...);
然后只消耗15个字节(假定您的数组arr
具有此长度),它们将被复制到arr
,nb
将为15个字节,而在内部缓冲区中,我们只剩下5个字节
如果我们打电话
nb = recv(socket, arr, 100,...);
然后将20个字节复制到arr
,nb
将为20,内部缓冲区将为空
这表明:
send()
- 您必须始终检查
返回(recv
)以了解读取了多少字节nb
- 您无法知道在每个
调用中发送了哪些字节。“消息”的划分取决于您send()
- 您没有读取消息,也没有读取字符串(以null结尾的字符数组),您只是读取字节。然后,您不能只调用
来查看接收到的字节printf(“%s”,arr)
一段代码非常适合进一步分析。您能发布代码吗?尽管如此,还是要保持冷静!不可能。例外情况是带有缓冲区溢出的UDP,但它无论如何都会执行您想要避免的操作TCP连接创建一个没有明确边界的数据流。数据边界由应用程序定义。您的应用程序必须准备好执行部分接收操作,并且能够在接收到完整数据时进行检测。m