是否有早干嘛去了N将优先于对流水线错误恢复选择性重复任何原因?
显然,SR需要在接收机端缓冲区(大小合适),是其唯一的弱点是什么?
任何情况下GBN将专门较受欢迎?
是否有早干嘛去了N将优先于对流水线错误恢复选择性重复任何原因?
显然,SR需要在接收机端缓冲区(大小合适),是其唯一的弱点是什么?
任何情况下GBN将专门较受欢迎?
选择重是处理UDP的不可靠性更加智能和高效的方式。
但是,只有当它的落实到位。 如果我们很好地实现它,然后我们并不需要担心接收缓冲区。
例如,如果你选择线程方式,那么它很容易将数据保存在缓冲区中。 现在你不需要做一个单一的缓冲区整个初来乍到的数据。
所以线程的方式其实是这样的:
packetCounter
用于这一目的。 waitingQueue[thisPacketNumber] = true;
所以这是它while循环的一部分。 我们不需要一个单独的缓存来存储所有这些数据包或数据包,他们的兄弟姐妹先前的(包)之前抵达。
所以,现在我们有两个挑战 ,一个是要找到合适的数据结构,用于分别存储每个数据包,另一个是保持我们的线程队列喷井。
让我们先来看看我们的第二个挑战的解决方案。
这是我们的职责,我们要通过我们的线程每个原始数据包。
//this is our packetQueue
//Each packet will be alloted one instance of this functionality using threads
//So here, we have packetNumber of each respective packet
//Each packet will call wait(on Its Respective Semaphore) , shown below.
//Since we are going to initiate there respective semaphores from 0;
//They will enter in a waiting state and will only awake after getting signal from somewhere else or another packet.
//So As we saw in the while loop section, we are signaling the current packet if it's next to last saved packet.
//Once this packet got signaled, it will perform it's task, i.e. saving this packet into file.
//*****Increment the packetCounter++
//And then check if next packet in the sequence is waiting in the queue.....
//here we are using waitingThread[] boolean array for that purpose, you can use waitingQueue[] as it's name.
//if yes then signal next packet.
//And **TADA** it's done
unsigned long CALLBACK packetQueue(void *pn){
int packetNumber = (int) pn;
wait(packet[packetNumber]);
char *dt = dataBucket[packetNumber]->data;
save_line_into_file(dt);
waitingThread[packetNumber] = false;
packetCounter++;
if(waitingThread[packetNumber+1]){
signal(packet[packetNumber+1]);
}
}
类型声明可以在Windows和Linux有所不同。 这是一个适用于Windows。
正如你可以在提供代码的注释读了它的功能,我们可以谈谈未来的挑战,即第一个挑战 。
数据结构,分别保存每个数据包。
我们简单地定义一个结构和分配一些内存,它的指针。
因此,我们有:
typedef struct{
char data[200];
} DataBuffer;
DataBuffer* dataBucket[ESTIMATED_NO_OF_PACKETS];
ESTIMATED_NO_OF_PACKETS
可以是任意数量取决于你的估计接收数据的大小(无需是正确的),例如500
或者我们使用类似回收站缓冲区,通过保存到文件后释放指针的内存。 我们可以使用基地和窗口方法,它是这样的:
Set window = 100
AND base = 0
AND ESTIMATED_NO_OF_PACKETS = 100;
并成功地保存100个数据包后使碱= 100,所以我们可以从这样缓冲器访问数据*dataBucket[base+thisPacketNumber];
而且不要忘了释放每个指针的内存后,每次保存行动。
所以最后这是我们如何当原始数据包处理部分将会是什么样的:
//After sending ACK of this packet
//We can check if this is duplicate packet or not
//if(original){...
//Create Semaphore for this packetThread
packet[packetNumber] = create(0);
//Create Thread for this packet
//We gonna treat each request equally
//that's why we are putting each thread in queue.
//And a dataBucket Structure to pass parameters to thread
dataBucket[packetNumber] = (DataBuffer*)malloc(sizeof(DataBuffer));
strcpy(dataBucket[packetNumber]->data, data);
CreateThread(NULL,0,packetQueue,(void *)packetNumber,0,&tid);
//Now check if this the next packet in queue of not.
//If yes then signal this packet
//else put it in queue
if((packetCounter+1) == packetNumber){
signal(packet[packetNumber]);
}else{
waitingThread[packetNumber] = true;
}
此代码是一个只有Windows兼容的,但你可以很容易地改变他们为Linux或Mac
其他一些有用的功能:
void wait(semaphore h) { // wait for a semaphore
WaitForSingleObject( h, MAXLONG);
}
void signal(semaphore h) { // signal a semaphore
ReleaseSemaphore(h,1,NULL);
}
semaphore create(int v) { // create a semaphore with value v
return CreateSemaphore(NULL,(long)v, MAXLONG, NULL);
}
不要给一些反馈,如果我忘了什么要补充的。