- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我已经看了几个小时了。我已经尝试了我能想到的一切,坦率地说这没有意义。我积极地使用套接字发送和接收没有问题,但是一旦我将数据更改为不同的消息,相同的样式,它就会停止接收。我正在使用 TCP。我有一个管理器进程最多发送 N strip 有表数据的路由器消息。我后来发送了一个相同样式的数据包,它接收到它,然后停止接收....代码返回到循环的顶部,但只是没有获得更多数据。
哦,我正在使用的网络代码是对 beejs TCP 服务器客户端代码的复制和粘贴。 http://beej.us/guide/bgnet/output/html/multipage/clientserver.html
管理线程,这部分工作
for(vector< vector<int> >::iterator it = table.begin(); it!=table.end(); ++it ){
vector< int > d = *it;
for(vector<int>::iterator itA = d.begin(); itA!=d.end(); ++itA ){
cout << "Sending... "<< *itA << endl;
s <<*itA<<" ";
}
if (send(new_fd, s.str().c_str(), 13, 0) == -1)
perror("Serv:send");
sleep(2);
logs << "Sent to router " << i <<":\n" << s.str();
writeLog(logs.str().c_str());
s.str("");
logs.str("");
}
s<<"done";
if (send(new_fd, s.str().c_str(), 13, 0) == -1)
perror("Serv:send");
writeLog(s.str().c_str());
管理 2,只有第一条消息通过
for(vector <vector <int > >::iterator it = toSendPackets.begin(); it != toSendPackets.end(); ++it){
sleep(3);
vector<int> tsp = *it;
int a,b,c = 0;
for(vector<int>::iterator itr = tsp.begin(); itr != tsp.end(); ++itr){
if(c==0){
a = *itr;
}
if(c==1){
b = *itr;
}
c++;
}
ss.str("");
ss << a << " " << b;
for(int i = 0; i < numN; i++){
int curSoc = socketList[i];
stringstream sl;
sl<<"sent:"<< ss.str().c_str();
cout << "sending.. " << ss.str() << " to " << i << endl;
if (send(curSoc, "HOP", strlen("HOP")+1, 0) == -1)
perror("Serv:send");
sleep(2);
if (send(curSoc, ss.str().c_str(), strlen(ss.str().c_str())+1, 0) == -1)
perror("Serv:send");
writeLog(sl.str().c_str());
sleep(1);
}
}
路由器代码。
上面的manager code和manager code 2都发送到这部分代码。它得到第一个发送,在这种情况下是“HOP”,然后什么都没有?我删除了 HOP 数据包解析,所以它应该只说明已读取某些内容。
if(tid == 0){// TCP
stringstream s;
bool proc = true;
while(!doneFlag){
proc = true;
cout << "TCP RECEIVING... " << endl;
int numbytes = 0;
while(numbytes==0){
if ((numbytes = recv(sockfd, buf, MAXDATASIZE, 0)) == -1) {
perror("recvROUTERThread0");
exit(1);
}
}
buf[numbytes] = '\0';
numbytes = 0;
if(strcmp("Quit",buf)==0){
writeLog("Quit read",outName);
doneFlag = true;
close(net.sockfd);
floodUDP("Quit");
pthread_exit(NULL);
}
else if(strcmp("HOP",buf)==0){
cout << "HOP READ" << endl;
numbytes = 0;
while(numbytes==0){
if ((numbytes = recv(sockfd, buf, MAXDATASIZE, 0)) == -1) {
perror("recvROUTERThread0");
exit(1);
}
}
s << id << "R: Receiving a routing command! " << buf;
cout << s.str().c_str() << endl;
writeLog(s.str().c_str(),outName);
HOPpacket hpo = genHopOrig(s.str().c_str());
if(hpo.s == atoi(id)){
printHOP(hpo);
// cout << "PACKET " << pr << endl;
stringstream sl;
char* hop = generateHopPacket(hpo);
sl << "Generating HOP packet and sending.. " << hop;
writeLog(sl.str().c_str(),outName);
sendHOP(hop);
}
}
else{
cout << "Table row data from manager" << endl;
s.str("");
s << id << "R: MANAGER MESSAGE: " << buf << endl;
cout << s.str() << endl;
writeLog(s.str().c_str(),outName);
int intID = atoi(id);
vector <int> tr = processTR(buf,intID,basePN);
table.push_back(tr);
}
}
}
我的输出。在这种情况下,有 10 个路由器在运行。请注意,我没有更改打印说明它先发送 HOP 然后 0 5 ..
sending.. 0 5 to 0
HOP READ
WRITTING Manager log:12-11-23::4:6:26:
sent:0 5
sending.. 0 5 to 1
HOP READ
WRITTING Manager log:12-11-23::4:6:29:
sent:0 5
sending.. 0 5 to 2
HOP READ
WRITTING Manager log:12-11-23::4:6:32:
sent:0 5
sending.. 0 5 to 3
HOP READ
WRITTING Manager log:12-11-23::4:6:35:
sent:0 5
sending.. 0 5 to 4
HOP READ
WRITTING Manager log:12-11-23::4:6:38:
sent:0 5
sending.. 0 5 to 5
HOP READ
WRITTING Manager log:12-11-23::4:6:41:
sent:0 5
sending.. 0 5 to 6
HOP READ
WRITTING Manager log:12-11-23::4:6:44:
sent:0 5
sending.. 0 5 to 7
HOP READ
WRITTING Manager log:12-11-23::4:6:47:
sent:0 5
sending.. 0 5 to 8
HOP READ
WRITTING Manager log:12-11-23::4:6:50:
sent:0 5
sending.. 0 5 to 9
HOP READ
WRITTING Manager log:12-11-23::4:6:53:
sent:0 5
sending.. 3 9 to 0
WRITTING Manager log:12-11-23::4:6:59:
sent:3 9
sending.. 3 9 to 1
WRITTING Manager log:12-11-23::4:7:2:
sent:3 9
sending.. 3 9 to 2
WRITTING Manager log:12-11-23::4:7:5:
sent:3 9
sending.. 3 9 to 3
WRITTING Manager log:12-11-23::4:7:8:
sent:3 9
sending.. 3 9 to 4
WRITTING Manager log:12-11-23::4:7:11:
sent:3 9
sending.. 3 9 to 5
WRITTING Manager log:12-11-23::4:7:14:
sent:3 9
sending.. 3 9 to 6
WRITTING Manager log:12-11-23::4:7:17:
sent:3 9
sending.. 3 9 to 7
WRITTING Manager log:12-11-23::4:7:20:
sent:3 9
sending.. 3 9 to 8
WRITTING Manager log:12-11-23::4:7:23:
sent:3 9
sending.. 3 9 to 9
WRITTING Manager log:12-11-23::4:7:26:
sent:3 9
最佳答案
recv
数据时出现问题,TCP 是基于流的套接字而不是基于消息的套接字,因此如果您使用:
send( sock, buf1, len1, 0 ); // Send HOP, since it is small, you OS merge this
send( sock, buf2, len2, 0 ); // with next send!
然后尝试使用 recv
接收数据 不能保证您在对 recv
的 2 个单独调用中接收数据,因此您可能会在一次调用中接收到两个发送的缓冲区到 recv
:
recv( sock, buf, len, 0 ); // This may receive both buffers in one call
因此,您下次调用 recv
时,将因第一次调用时已收到的数据而被阻止!它们也可能是另一个问题,因为当您发送大缓冲区时,recv
收到的数据可能少于使用 send
传递的单个消息。
您必须定义一个协议(protocol)来定义接收流中消息的结尾,然后根据该协议(protocol)接收您的数据。例如,您可以先发送消息的长度或定义指示消息结束的内容(例如 \0
或 \r\n
)。
抱歉,我对错误的描述不完整。在您的评论中,您说您增加了 HOP
消息大小!但这当然不是一个好习惯,而且增加的大小太小以至于永远不会强制操作系统立即发送它(实际上没有强制操作系统这样做的特定大小)。如果您希望操作系统立即发送您的数据,您应该使用 TCP_NO_DELAY
选项禁用 Nagle 算法,但在此之前请先查看 How do I use TCP_NODELAY? . 这样做也不是一个好的做法,除此之外,这样做会导致您的数据包在您调用 send
时立即发送,但它不会强制接收方的操作系统单独接收消息!! 那么正确的做法是什么?
我详细说明问题:
// I don't know exact value of MAXDATASIZE but I will assume it is 128
char buf[ MAXDATASIZE ];
int numbytes = recv( sock, buf, MAXDATASIZE, 0 );
if( numbyte == -1 ) {
// Handle error
}
// I assume HOP_MSG is a defined constant that contain value of HOP message
if( strcmp(buf, HOP_MSG) == 0 ) { // <-- (1)
while( (numbytes = recv(sock, buf, MAXDATASIZE, 0)) != -1 ) { // <-- (2)
if( numbytes == 0 ) break;
}
if( numbytes == -1 ) {
// Handle error
}
}
但是等等!在用 (1)
标记的那一行 我假设 recv
完全读取 HOP_MSG
并且只读取 HOP_MSG
,但是为什么?? 正如我之前所说,TCP
是一个流协议(protocol),它没有消息边界,所以它可能只读取 2 个字节!!或者它读取 1KB
( 这肯定比 HOP_MSG
多,那我该怎么办??
工作答案如下:
int receive_till_zero( SOCKET sock, char* tmpbuf, int& numbytes ) {
int i = 0;
do {
// Check if we have a complete message
for( ; i < numbytes; i++ ) {
if( buf[i] == '\0' ) {
// \0 indicate end of message! so we are done
return i + 1; // return length of message
}
}
int n = recv( sock, buf + numbytes, MAXDATASIZE - numbytes, 0 );
if( n == -1 ) {
return -1; // operation failed!
}
numbytes += n;
} while( true );
}
void remove_message_from_buffer( char* buf, int& numbytes, int msglen ) {
// remove complete message from the buffer.
memmove( buf, buf + msglen, numbytes - msglen );
numbytes -= msglen;
}
void main() {
SOCKET s;
char buf[ MAXDATASIZE ];
int numbytes = 0, msglen;
// Initialize socket and connect to server, you already do that
while( true ) {
msglen = receive_till_zero( s, buf, numbytes );
if( msglen == -1 ) {/* Handle error */}
if( !strcmp(buf, HOP_MSG) ) {
remove_message_from_buffer( buf, numbytes, msglen );
msglen = receive_till_zero( s, buf, numbytes );
if( msglen == -1 ) {/* Handle error */}
std::cout << "Message received from server: " << buf << std::endl;
remove_message_from_buffer( buf, numbytes, msglen );
}
}
}
通过调试这段代码你肯定会明白它的目的,receive_till_zero
假设之前调用 recv
时缓冲区中已经有一些待处理的数据,所以它会首先检查如果缓冲区中是否有完整的消息,并且它永远不会假设仅通过一次调用 recv
就可以接收数据,因此它将循环调用 recv
直到它看到缓冲区中的 \0
。在我们处理完缓冲区中的数据后,我们调用 remove_message_from_buffer
来吃掉该数据,并且只吃掉该数据,而不仅仅是从缓冲区的开头开始接收,因为它们可能已经在缓冲区中有一些数据。
如您所见,代码有点复杂,为了更好的编程模型和更好的 C++ 代码,您可以使用 boost::asio具有非常好的设计并与 C++ 和 iostream
关于C++ 套接字只接收先发送?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13527927/
我正在使用 voip 推送通知制作 ios 应用程序。 我想从 Node js 发送 voip 推送通知,但不是很好。 我阅读了本教程 CallKit iOS Swift Tutorial for V
我编写了一个服务器,当浏览器尝试连接到某些站点时,它会检查黑名单并发回 404,但是当我调用 send() 时没有错误,但消息不会出现在网络上浏览器,除非我关闭连接? 有什么建议吗? 接受来自浏览器的
#include int main() { char c = getchar(); //EOF (ctrl + d ) while( ( c = getchar() ) != '?'
我正在尝试使用MailMessage对象通过PowerShell发送电子邮件。该脚本使用Import-CSV来使用文件,然后在电子邮件正文中使用ConvertTo-HTML。由于我要发送的电子邮件客户
我需要创建一个脚本,每 30 秒对网络流量进行一次采样并存储发送/接收的字节。该数据随后用于绘制图形。我编写了一个在 Windows 2012 上完美运行的程序,但我意识到某些 cmdlet 在以前的
我正在运行“autoit3.chm”文件。当它运行时,我想发送一个向下键箭头,但它不起作用: $file = FileGetShortName("C:\Users\PHSD100-SIC\Deskto
当我使用网络浏览器测试我的程序时,我可以很好地写入套接字/FD,所以我决定循环它并在连接中途切断连接,我发现了一个问题。 send() 能够在套接字不可用时关闭整个程序。我认为问题在于该程序陷入了第
我正在运行“autoit3.chm”文件。当它运行时,我想发送一个向下键箭头,但它不起作用: $file = FileGetShortName("C:\Users\PHSD100-SIC\Deskto
所以我试图向自己发送数据并接收数据然后打印它,现在我已经测试了一段时间,我注意到它没有发送任何东西,事实上,也许它是,但我没有正确接收它,我需要这方面的帮助。 这就是我用来发送数据的
问题:开发人员创建自己的序列化格式有多常见?具体来说,我使用 java 本质上将对象作为一个巨大的字符串发送,并用标记来分隔变量。 我的逻辑:我选择这个是因为它几乎消除了语言依赖性(忽略java的修改
我必须在 Linux 上编写一个应用程序,该应用程序需要与具有自定义以太网类型的设备进行通信。甚至在如何编写这样的应用程序中也有很多解决方案。一个缺点是需要 root 访问权限(AFAIK)。之后释放
我有一个包含三个单选按钮选项的表单。我需要将表单数据提交到另一个文件,但由于某种原因,发送的数据包含所选单选按钮的值“on”,而不是 value 属性的值。 我尝试通过 post() 函数手动操作和发
基本上我想实现这样的目标: Process 1 Thread 1 Receive X from process 2 Thread 2 Receive Y from proces
我目前正在 Google App Engine 上开发一个系统,对它还很陌生,我正在使用 Java 平台进行开发。我在 servlet 之间发送 session 对象时遇到问题。我已经在 appeng
当我尝试将“this”(触发的元素)作为参数发送给函数时,函数收到“Object[Document build.php]”作为参数,而不是触发的元素。请让我知道我的错误: function set(a
我正在寻找让我的应用响应联系人 > 发送的魔法咒语。我希望能够接收联系人的 URI 以便检索联系人。谁有 list 过滤器/代码 fragment 吗? 最佳答案 我没有睾丸,但您可以尝试基于 ACT
关于我心爱的套接字的另一个问题。我先解释一下我的情况。之后我会告诉你是什么困扰着我。 我有一个客户端和一个服务器。这两个应用程序都是用 C++ 编写的,实现了 winsock2。连接通过 TCP 和
我看到了这篇文章 http://www.eskimo.com/~scs/cclass/int/sx5.html 但这部分让我感到困惑:如果我们已经使用 send_array 或 send_array_
我对这行代码有疑问。我必须将一个数据包带到一个端口并重新发送到接口(interface)(例如:eth0)。我的程序成功地从端口获取数据包,但是当我重新发送(使用 send())到接口(interfa
我正在尝试编写一个 X11 输入驱动程序,它可以使用我的 Android 手机上的触摸屏来移动和单击鼠标。我可以正常移动鼠标,但我无法让应用程序正确识别点击。我当前的代码位于 https://gist
我是一名优秀的程序员,十分优秀!