我在编写代码时遇到了一些困难,因为我不太了解。我有两个可以相互通信的PC的设置。它可以工作,但它只能发送单个字符。如果在没有IP地址参数的情况下执行命令,则一台PC就像服务器一样,另一台PC在给定服务器IP地址的情况下就像客户端一样连接到服务器。
代码全在这里:
$vars = array('12345:0','45678:0','78910:0','3434:1','2345:1');
$vacct = '';
foreach ($vars as $var)
{
$vinfo = explode(":", $var);
$vgroup = $vinfo[0];
if($vacct != $vinfo[1])
{
switchAccount("details");
$vacct = $vinfo[1];
}
}
我想要实现的是能够发送字符串而不是单个字符。我希望它的工作方式是增加它发送的字节大小而不是当前的单字节。我假设它可以工作的方式,假设一次发送和接收总大小为64字节。
答案 0 :(得分:0)
实际上你的问题区域实际上并不是很清楚。
我的解决方案如下。基本思想是分配相同大小的发送和接收缓冲区,将字符附加到键盘输入上的发送缓冲区,并在缓冲区满或用户点击返回键时传输缓冲区。
非阻塞send
函数可能不会立即发送整个缓冲区(see the docs)。我决定继续阻止,直到整个缓冲区被发送,所以我不必跟踪单独的输入和传输缓冲区。你可以改进这一点,我敢肯定。
接收部分只回显接收到的任何字节。一般情况下,无法知道其他用户是否已“完成”发送数据,因此我们只需打印首次调用recv
后收到的内容。
每次发送和接收后,我总是memset
缓冲区为全零,以防止丢失空终止符的奇怪行为。简单地将空字符附加到当前字符串的末尾会更加优化,但有时我会变得偏执。
这是我的代码:
#define BUFFER_SIZE 64
void chat (int socket_d)
{
char sendBuffer[BUFFER_SIZE] = { 0 };
char receiveBuffer[BUFFER_SIZE] = { 0 };
int bufferPosition = 0;
int charsSent = 0;
int charsReceived = 0;
while (true)
{
if (_kbhit ())
{
sendBuffer[bufferPosition++] = _getche();
if (sendBuffer[bufferPosition - 1] == '\r' || bufferPosition == BUFFER_SIZE - 1)
{
// This defeats the purpose of a non-blocking socket, I know.
// You can do better by keeping separate buffers for sending and
// collecting input.
while (charsSent < bufferPosition)
{
charsSent += send(
socket_d,
&sendBuffer[charsSent], // Treats the address of a character as a string.
bufferPosition - charsSent, // Only send the part that hasn't been sent yet.
0);
}
memset(sendBuffer, 0, bufferPosition); // Paranoid.
bufferPosition = charsSent = 0;
cout << "\n";
}
}
charsReceived = recv (socket_d, receiveBuffer, BUFFER_SIZE, 0);
if (charsReceived <= 0)
{
if (WSAGetLastError() != WSAEWOULDBLOCK) // A real problem - not just avoiding blocking.
{
cout << "Terminated " << WSAGetLastError() << "\n";
return;
}
}
else
{
cout << receiveBuffer;
if (receiveBuffer[charsReceived - 1] == '\r')
cout << "\n";
memset(receiveBuffer, 0, charsReceived); // Super paranoid.
}
}
}
现在,在支持UTF-8或至少wchar_t
之前,我不会真的认为这是“好”。 ASCII缺少很多人们希望能够在真实聊天应用程序中使用的字符。
PS - 根据Visual Studio 2013,不推荐使用inet_addr
函数。我用inet_ptons
代替了。 Here's the documentation on the Winsock implementation for it