2014-10-10 67 views
1

在C,TCP中的服务器/客户端中,如果我在程序中连续读取/写入,会发生什么情况?这是否可能,或者我是否一直遵循结构“客户端写 - >服务器读 - >服务器写 - >客户端读”?C套接字 - 连续读写,会发生什么?

是否有可能做到这样的事情?或者是否有可能从客户端的第二次读取中接收到服务器中第三次写入的数据,以及其他这样的坏事情?

client.c

write (1) 
read (2) 
read (3) 
read (4) 

server.c

read (1) 
write (2) 
write (3) 
write (4) 
+0

这不是一件坏事 - 它是八位字节(字节),流发生的情况。用户级没有“数据包”。没有'消息'长于一个字节。你似乎正在描述TCP的正常行为。 – 2014-10-10 15:51:26

+0

@MartinJames也许我的解释并不好,我的意思是,如果从read(2)接收到write(3),这是一件坏事,因为来自wirte(3)的数据将被读取2),这是一个不起眼的行为。这可能吗? – testermaster 2014-10-10 15:53:46

回答

3

是的,这是可能的。读取将会阻塞(默认情况下),直到数据可用于在套接字上读取。没有必要尝试按特定顺序安排读取和写入,您的程序将等待,直到在read()调用返回之前有东西要读取。

您的代码将导致此:

Server blocks in read() 
Client write()s 
Client blocks in read() 
Server receives data, read() returns 
Server write()s three times 
Client receives data, read(1) returns 
Client's read(2) is called and returns as soon as data arrive 
Client's read(3) is called and returns as soon as data arrive 

在一个非常快的链接有可能是服务器的write()S和读取客户端()秒发生在大致相同的时间,甚至交错,但服务器的write()将始终按顺序排列,客户端的read()将始终按顺序排列。

如果套接字是SOCK_STREAM,则数据排序被保留,例如。像你问的TCP或UNIX套接字。因此,读取(2)将始终返回写入(2)中为TCP套接字写入的数据。

如果您使用UDP套接字(SOCK_DGRAM的默认设置),您可能会发现这些消息是乱序接收的,或根本没有收到。

+0

......如果使用了阻塞套接字 – alk 2014-10-10 15:58:29

+0

套接字块默认情况下是阻塞的,至少对于POSIX/Unix套接字。 – 2014-10-10 15:59:10

+0

如果从read(2)接收到write(3),这是一件坏事,因为来自wirte(3)的数据将被read(2)读取,这是一个未被考虑的行为。这是可能的吗?或者阻塞使得发生这种情况不可能发生? – testermaster 2014-10-10 15:59:35

4

TCP传输的数据流。

因此n调用write可能导致以M调用read(与N> 0和M> 0和N = <传输的字节数,M = <传送的字节数)。

然而,在各种写入和读取之间保存发送字节的顺序。

作为一个直接的结果,你不能只使用writeread的普通数量的调用来同步进程。您需要添加例如每个步骤要传输的字节数。

简而言之:您需要TCP流顶部的应用程序级协议。

+0

嗯,所以我在问题的评论中写了什么,可能与否? “如果从read(2)接收到write(3),这是一件坏事,因为来自wirte(3)的数据将被read(2)读取,这是一个未被考虑的行为。这可能吗?“ – testermaster 2014-10-10 15:55:35

+0

你不能只使用”write“和”read“调用的简单数量,以便同步你的进程,你需要添加每步要传输的字节数 – alk 2014-10-10 16:03:01

+0

是的我知道,我用一个普通数字在这里解释一下情况我想知道如果写入/读取的顺序是保存程序,并且你在回答中回答了非常感谢你 – testermaster 2014-10-10 16:04:28