如何循环读取c ++套接字。
stringstream ss;
while (1) {
char buf [2];
ssize_t e = read(fd, buf, 2);
ss << buf[0];
ss << buf[1];
cout << e << endl;
cout << buf[0] << endl;
cout << buf[1] << endl;
if (e <= 0) {
break;
}
}
string msg = "";
ss >> msg;
当我telnet并输入hello然后输入测试时,我得到了
2
h
e
2
l
l
2
o
1
它只是在那里等待,没有循环。发生了什么,我怎么读套接字?
如何使用
表示EOF远程登录
写入(fd,buf,bufSize)的上下文中的buf;
答案 0 :(得分:1)
你是什么意思没有循环?错误更多,按回车键,你会看到更多输出..
如果你完成了,你必须按Ctrl + D来表示输入结束(EOF)。
答案 1 :(得分:1)
如何使用
表示EOF1)telnet
2)写入(fd,buf,bufSize);
的上下文中的buf
首先,你想发出的不是EOF。它是“消息结束”或“您刚刚收到的数据是一个完整的协议数据单元,您现在应该处理它”。答案是,然而你想要,只要双方都同意。
例如,您可以专门保留~
字符以标记邮件的结尾。为了表明消息的结束,一方发送~
。另一方知道,当它收到~
时,之前的所有内容都是一条消息,其后的所有内容都是新消息。
您还可以在发送实际消息之前发送消息的长度。您可以在文本后跟零字节或换行。或者您可以将每条消息都排成一行。
你可以这样做,但在你的特定应用程序中最有意义,但实际上你必须这样做。
有两种情况,TCP会为您执行此操作:
1)当一方完全发送并知道另一方不再发送任何数据时,它可以在套接字上使用close
。另一方将阅读已发送的其余数据,然后read
将返回0
。
2)当一方不再发送任何数据但另一方可能发送更多数据时,它可以shutdown
其连接方。它永远不会发送更多数据。另一方将知道此关闭,如果专门编码,可以继续发送数据,直到它关闭它的一半。然后另一方的read
将返回零。 (请注意,如果你对一个非设计的程序执行此操作,它可能会感到困惑,并且没有意识到它仍然可以向您发送数据。)
否则,一切都取决于你。
答案 2 :(得分:1)
TCP数据包是流,而不是文件。由你来决定如何读取流。
一般情况下,如果你在一端写20个字节,你会在一次读取的另一端获得20个字节,除非使用一些常见的tcp / ip选项。
下面有一些假设。一些假设是:
假设所有脚手架代码都存在。
假设我犯了错误并自己调试。
假设处理所有字节顺序问题。
假设您足够聪明,不要将浮点类型发送为二进制文件。
有些程序员选择使用长度前缀数据包并读取长度字节(2),然后读取该长度所代表的字节数,就像这样。
unsigned char buffer[MAX_CHAR] = "";
unsigned char length = 0;
int bytesRead = 0;
read( fd, sizeof( length ), &length );
// Handle failure from read
while( bytesRead < length )
{
int readRv = read( fd, &buffer[bytesRead], length - bytesRead );
if( readRv <= 0 ) // 0 usually means socket was closed. -1 is an erro
{
// Handle socket error/closed socket
}
else if( readRv < length )
{
bytesRead += readRv;
}
else if( readRv == length )
{
bytesRead = readRv;
break;
}
}
一些程序员阅读可用内容并查找数据包结束标记
unsigned char buffer[MAX_CHAR] = "";
unsigned char length = 0;
int bytesRead = 0;
int readRv = read( fd, buffer, sizeof( buffer ) );
int eopFound = 0;
if( (eopFound = findEndOfPacketMarker( buffer )) > 0 )
{
// Less than 0 = error.
}
else if( eopFound == 0 )
{
// No end of packet, must read more bytes here
}
else
{
// Found an end of packet marker
}
// Here you deal with bytes that are "over read"
// Either the
// 1) packet was bigger than buffer,
// 2) there were bytes left over after the EOP marker
// 3) Martians crapped in your code and screwed it all up. :)
有些程序员使用固定大小的数据包和数据包类型id
int packetType;
unsigned char buffer[MAX_CHAR] = "";
unsigned char length = 0;
int bytesRead = 0;
read( fd, sizeof( packetType ), &packetType );
read( fd, getLengthFromPacketType( packetType ), buffer );
这应该涵盖大多数事情......
如果您有更多问题,请在评论中询问@
JimR thingy,以便它显示为我阅读的消息。