¹öÆÛ¸µ(Buffering), ÇÏ´Â ÀÏ·Î ºÁ¼´Â QueuingÀÌ´Ù.
- 1 Å¥À×ÀÇ ¸ñÀû
- 2 Å¥À×ÀÇ ±¸Çö
- 2.1 STL queue¸¦ ÀÌ¿ëÇÑ ±¸Çö
- 2.1.1 Text Data Queuing ±¸Çö
- 2.1.2 Binary Data Queuing ±¸Çö
- 2.1.3 Å¥ÀÇ °³¼± : °¢ ¿ä¼ÒµéÀÇ Å©±â¸¦ Àû´çÇÑ »çÀÌÁî·Î ¸¸µç´Ù
- 2.2 Å¥ÀÇ Á÷Á¢ ±¸Çö
- 3 ¼Ò½º
Å¥´Â ÀڷᱸÁ¶ Ư¼º»ó FIFO(First In First Out)ÀÇ ±¸Á¶¸¦ °¡Áø´Ù. ÀÚ·áÀÇ Ã³¸® ¼ø¼¸¦ ÈåÆ®¸®Áö ¾Ê°í ÀϽÃÀûÀ¸·Î ½×±â À§Çؼ »ç¿ëµÇ´Âµ¥,
1. ¼ÒÄÏÇÁ·Î±×·¡¹Ö¿¡¼´Â µé¾î¿Â ÀڷḦ ÀÏ´Ü ÀÐ¾î¼ ½×°í, ½Ã°£ÀÌ °É¸®´Â ÀÚ·áºÐ¼® ¹× 󸮴 µÚ·Î Çϱâ À§Çؼ (ÀÌ·¸°Ô ÇÔÀ¸·Î½á ÃÖ°íÀÇ ¼ÒÄÏ È¿À²À» À̲ø¾î³½´Ù) »ç¿ëÇÑ´Ù. (Read Buffering)
2. WOULDBLOCK : send ȤÀº write ¿¡¼ EWOULDBLOCKÀÌ ¹ß»ýÇÏ´Â °æ¿ì, Áï ¿î¿µÃ¼Á¦ÀÇ ³»ºÎ ¼ÒÄϹöÆÛ°¡ °¡µæÂ÷¼ ÀϽÃÀûÀ¸·Î µ¥ÀÌÅÍ ¼Û½ÅÀ» ÇÒ ¼ö ¾ø´Â °æ¿ì¸¦ À§ÇØ »ç¿ëÇÑ´Ù. ÀϽÃÀûÀ̱⠶§¹®¿¡ ¿¡·¯¶ó°í »ý°¢Çؼ ¿¬°áÀ» ²÷¾î¹ö¸± ¼öµµ ¾ø°í, ±×·¸´Ù°í ¸øº¸³»°í ³²Àº µ¥ÀÌÅ͸¦ µû·Î º¸°üÇؼ ó¸®Çϱ⵵ ¹ø°Å·Ó´Ù.
3. Small Packet : 1¹ÙÀÌÆ®¸¦ º¸³»±âÀ§ÇÑ ÆÐŶ¿À¹öÇìµå´Â ¾à 64¹è¿¡ ´ÞÇÑ´Ù. ³×Æ®¿öÅ© ´ë¿ªÆøÀÌ 100Mbps ÀÇ Fast Ethernet À̶ó°í ÇÒ¶§¿¡, 1¹ÙÀÌÆ®¾¿ÀÇ ÆÐŶ¸¸À» ¿¬´Þ¾Æ ¼Û½ÅÇÏ¸é °Ü¿ì 1.6MbpsÀÇ ÀڷḦ Àü¼ÛÇÒ ¼ö ÀÖ´Ù. ¿î¿µÃ¼Á¦´Â ÀÌ ¹®Á¦¸¦ ÇÇÇØ°¡±â À§ÇØ ³»ºÎ ¾Ë°í¸®ÁòÀ» ÀÌ¿ëÇؼ ÃÖ´ëÇÑ µ¥ÀÌÅ͸¦ ¹¾î¼ Àü¼ÛÇÑ´Ù. ¾îÇø®ÄÉÀÌ¼Ç Â÷¿ø¿¡¼µµ ÀÛÀº µ¥ÀÌÅ͵éÀ» ¹¾î¼ ÃÖ´ëÇÑ Àü¼ÛÇϱâ À§ÇØ Send BufferingÀ» ÀÌ¿ëÇÑ´Ù.
2 Å¥À×ÀÇ ±¸Çö #
2.1 STL queue¸¦ ÀÌ¿ëÇÑ ±¸Çö #
2.1.1 Text Data Queuing ±¸Çö #
#include <iostream>
#include <queue>
using namepsace std;
int main(void)
{
queue<char *> binq;
char *p_pop;
binq.push("Hello ");
binq.push("World\n");
while(!binq.empty()){
cout << binq.front();
binq.pop();
}
}
queue ÅÆÇø´ÀÇ push, front, pop À» ÀÌ¿ëÇؼ ÀڷḦ ³Ö°í »©°í Ãâ·ÂÀ» ÇØ º¸¾Ò´Ù. ÅؽºÆ®ÀÇ NULL Terminator 󸮰¡ Á¶±Ý ¹ÌÈíÇÏÁö¸¸, ÀÌ°ÍÀ¸·Îµµ ±¦Âú´Ù. ´Ù¸¸, Åë½Å¿¡ »ç¿ëÇÒ ÀÚ·áµéÀÌ ¹ÙÀ̳ʸ® µ¥ÀÌÅͶó¸é(Áï 0, NULLÀ» Æ÷ÇÔÇÏ´Â °ÍÀ̶ó¸é) ÀûÀýÄ¡ ¾ÊÀ¸¹Ç·Î ¾à°£ÀÇ º¸¿ÏÀ» ÇÊ¿ä·Î ÇÑ´Ù.
2.1.2 Binary Data Queuing ±¸Çö #
#include <queue>
#include <iostream>
using namespace std;
class TBinData
{
public :
int size;
char *buffer;
TBinData(const int nsize, const char* buf)
{
size = nsize;
buffer = new char[nsize];
memcpy(buffer, buf, nsize);
};
~TBinData()
{
delete []buffer;
}
};
int main(void)
{
queue<TBinData *> binq;
TBinData Data1(12, "Hello World\n");
TBinData Data2(12, "Bin Queuing\n");
binq.push(&Data1);
binq.push(&Data2);
char buf[1024];
while(!binq.empty()){
TBinData *data = binq.front();
memcpy(buf, data->buffer, data->size);
// Å×½ºÆ® Ãâ·ÂÀ» À§ÇØ Å͹̳×ÀÌÅÍ ºÙÀÓ
buf[data->size] = 0;
cout << buf;
binq.pop();
}
return 0;
}
?TBinData¶ó´Â Ŭ·¡½º¸¦ ¸¸µé¾î, ÀÌ Å¬·¡½ºÀÇ Æ÷ÀÎÅ͵éÀ» Å¥·Î °ü¸®Çϵµ·Ï ÇÏ¿´´Ù. ÀÌ·¸°Ô ÇØ ³õ°í º¸´Ï ¸¸¾à pushµÇ´Â µ¥ÀÌÅ͵éÀÌ ¸ðµÎ 1 ¹ÙÀÌƮ¥¸®¶ó¸é.. ¸Þ¸ð¸®¿¡ ¸¹Àº ³¶ºñ°¡ »ý±æµíÇÏ´Ù. ¾îÂ÷ÇÇ ¹ÙÀ̳ʸ® ½ºÆ®¸²À̶ó¸é, ¿©·¯°³ÀÇ µ¥ÀÌÅ͸¦ Çϳª·Î ÇÕÃijöµµ ¹®Á¦´Â ¾øÀ» µí ÇÏ´Ù.
2.1.3 Å¥ÀÇ °³¼± : °¢ ¿ä¼ÒµéÀÇ Å©±â¸¦ Àû´çÇÑ »çÀÌÁî·Î ¸¸µç´Ù #
Àû´çÇÑ »çÀÌÁî¶õ °ú¿¬ ¾ó¸¶Àϱî? ¿©±âÀú±â µèÀÚÇÏ´Ï ¾î·°Å³ª
1400 À̶ó°íµé ÇÑ´Ù. ÀÌ 1400 À̶ó´Â °ªÀº ±×·¯´Ï±ñ Çѹø¿¡ ¼ÒÄÏÀ¸·Î ½î±â¿¡ Àû´çÇÑ °ªÀ̶ó´Â ÀǹÌÀÌ´Ù. ÀڷᱸÁ¶µéµµ ÀÌ¿¡ ¸ÂÃç¼ ÀÛ¼ºÇϸé ÁÁÀ»µí ÇÏ´Ù.
class TBinData
{
public :
int size;
char *buffer;
TBinData(const int nsize, const char* buf)
{
size = nsize;
buffer = new char[nsize];
memcpy(buffer, buf, nsize);
};
~TBinData()
{
delete []buffer;
}
int Add(const int nsize, const char *buf)
{
int newsize = size + nsize;
// »õ·Î¿î »çÀÌÁî·Î ÇÒ´ç
char *tmpbuf = new char[newsize];
// µÎ°³ÀÇ µ¥ÀÌŸ º¹»ç
memcpy(tmpbuf, buffer, size);
memcpy(&tmpbuf[size], buf, nsize);
// ±âÁ¸¹öÆÛ »èÁ¦ÈÄ »õ ¹öÆÛ ´ëÀÔ
delete []buffer;
buffer = tmpbuf;
size = newsize;
return newsize;
};
};
////
queue<TBinData *> binq;
TBinData *LastData = NULL;
int AddNew(const int size, const char *buffer)
{
LastData = new TBinData(newsize, buffer);
binq.put(LastData);
return binq.size();
}
int main(void)
{
...
if(binq.empty()){
AddNew(size, buffer);
} else {
if(LastData->size + size <= 1400) LastData->Add(size, buffer);
else AddNew(size, buffer);
}
....
}
Å¥¿¡ µ¥ÀÌÅ͸¦ Ãß°¡ÇÒ¶§¿¡ ÀÌ¹Ì µé¾îÀÖ´Â µ¥ÀÌÅÍÀÇ »çÀÌÁî¿Í Ãß°¡ÇÏ·Á´Â µ¥ÀÌÅÍÀÇ »çÀÌÁîÀÇ ÇÕÀÌ 1400 ÀÌ ³ÑÁö ¾ÊÀº °æ¿ì¿¡´Â Å¥ÀÇ ¿ä¼Ò¸¦ ´Ã¸®Áö ¾Ê°í ±× °ª¸¸ Á¶Á¤Çß°í, ³Ñ¾î°¡´Â °æ¿ì ȤÀº ¾Æ¿¹ Å¥°¡ ºñ¾îÀÖ´Â °æ¿ì´Â Å¥ ¿ä¼Ò¸¦ »õ·Î Ãß°¡Çϵµ·Ï ÇÏ¿´´Ù. TBinData:
?:Add ÇÔ¼ö³»ºÎÀûÀ¸·Î Á¶±Ý º¹ÀâÇÏ°í È¿À²ÀÌ ÁÁÁö ¾Ê´Ù. ¿ª½Ã 1 ¹ÙÀÌƮ¥¸® push °¡ ¸¹À¸¸é ¼º´ÉÀÌ ¾ÆÁÖ¾ÆÁÖ ÁÁÁö ¾ÊÀ» µíÇÏ´Ù.
2.2 Å¥ÀÇ Á÷Á¢ ±¸Çö #
Á÷Á¢ ±¸ÇöÀº ÀÌ·¸°Ô ÇÒ °ÍÀÌ´Ù. Àû´ç·®ÀÇ ¹öÆÛ¸¦ ¹Ì¸® Àâ¾Æ³õ°í head ¿Í tail Æ÷ÀÎÅ͸¦ ¿Å°Ü´Ù´Ï¸é¼ push, pop À» ±¸ÇöÇÑ´Ù. ¸»Àº ½±Áö¸¸ ¿ª½Ã ±¸ÇöÇϱâ´Â ¸¸¸¸Ä¡ ¾Ê´Ù.
#include <string.h>
#include <queue>
#include <iostream>
using namespace std;
#define MAX_BUF 81920
class TBinQueue
{
protected :
char buf[MAX_BUF];
int head, tail;
public :
TBinQueue(void) : head(0), tail(0) {};
int Push(const int nsize, const char *buffer);
int Pop(const int maxsize, char *outbuffer);
int View(const int maxsize, char *outbuffer) const;
int Skip(const int skipsize);
};
int TBinQueue::Push(const int nsize, const char *buffer)
{
if(tail + nsize >= MAX_BUF) return -1; // overflow
memcpy(&buf[tail], buffer, nsize);
tail += nsize;
return (tail - head); // stored data size
}
int TBinQueue::Skip(const int skipsize)
{
head += skipsize;
if(head == tail){
head = tail = 0;
}
return (tail - head);
}
int TBinQueue::Pop(const int maxsize, char *outbuffer)
{
int viewsize = View(maxsize, outbuffer);
Skip(viewsize); // recalc head & tail
return viewsize;
}
int TBinQueue::View(const int maxsize, char *outbuffer) const
{
int copysize = maxsize;
int datasize = (tail - head);
if( datasize < maxsize ) copysize = datasize;
if( copysize < 1) return 0;
memcpy(outbuffer, buf, copysize);
return copysize;
}
int main(void)
{
TBinQueue binq;
char buffer[MAX_BUF];
binq.Push(13, "Hello World.\n");
binq.Push(13, "Bin Queuing.\n");
int nsize = binq.View(MAX_BUF, buffer);
binq.Skip(nsize);
buffer[nsize] = 0; // termination
cout << buffer;
return 0;
}