О памяти: В прикладных программах использется стандартный метод - malloc дергает системный вызов sbrk, который динамически расширяет BSS задачи.
В системных сервисах и драйверах используется переопределённый оператор new, который выделяет память из статических массивов.
Супервизор использует "поток виртуальных страниц" - абстракция над диспетчером страниц, которая используется для динамического выделения объектов определённого типа.
Сколько займёт уразанный TCP/IP? Ну вот навскидку - структура сокета:
class CSocket
{
CSocket * m_NextFree; // Next free socket in chain
// Socket section
int m_nDomain;
int m_nType;
int m_nProtocol;
// ???
int m_nStatus;
/// IP section
unsigned short m_mLocalPort;
unsigned short m_nRemotePort;
unsigned long m_mLocalAddress;
unsigned long m_nRemoteAddress;
// TCP section
typeTcpStates m_nState;
unsigned long m_nSequenceNumber;
unsigned long m_nAckNumber;
unsigned long m_nConnectionsAvailable;
bool m_SetAcknowledge;
// Data buffers
unsigned char m_pReceiverBuffer[1024];
unsigned int m_nReceivedBytes;
unsigned int m_nUserReceiveBufferSize;
// This section has been added after long long postponed period
// End of postponed section
// Variable that keep L4ThreadID of user's process that wait in accept()
unsigned int m_WaitingIncomingConnectionThreadID; // L4_Threaid_t
// Variable that keep L4ThreadID of sending user's process
unsigned int m_SendingThreadID; // L4_Threaid_t
unsigned int m_ReceivingThreadID; // L4_Threaid_t
//
CSocket * m_ParentSock; // Point to ACCEPT waiting socket ДШЫЕ
CSocket * m_PendingConnectionsChain; // Point to ACCEPT waiting socket ДШЫЕ
CSocket * m_PendingConnectionsNext; // Remote connected socket chain next element
//
public:
// ================== Public read-only poperties ==================
unsigned long LocalAddress() { return m_mLocalAddress; }
unsigned long RemoteAddress() { return m_nRemoteAddress; }
unsigned short LocalPort() { return m_mLocalPort; }
unsigned short RemotePort() { return m_nRemotePort; }
typeTcpStates SocketState() { return m_nState; }
unsigned long SequenceNumber() { return m_nSequenceNumber; }
unsigned long AckNumber() { return m_nAckNumber; }
unsigned long NumAvailableConn() { return m_nConnectionsAvailable; }
unsigned short Window() { return sizeof(m_pReceiverBuffer) - m_nReceivedBytes; }
bool AcknowledgeSet() { return m_SetAcknowledge; }
// ================== Public write-only poperties ==================
void AcknowledgeDone() { m_SetAcknowledge = false; }
void SetAcknowledgeNumber( unsigned long ack_no ) { m_nAckNumber = ack_no; m_SetAcknowledge = true; }
void SetSequenceNumber( unsigned long seq_no ); // { m_nSequenceNumber = seq_no; }
public:
CSocket();
virtual ~CSocket();
int Initialize( void );
int Create( int domain, int type, int protocol );
int Connect( unsigned int waiting_thread_id, char * socket_address_sorage, int size_of_address_sorage_buffer);
int Bind(struct sockaddr * sa);
int Listen(int max_connections);
int Accept( unsigned int waiting_thread_id);
int Send( unsigned int sending_thread_id, const unsigned char * pBuff, int nLength);
int Recv( unsigned int waiting_thread_id, unsigned char * pBuff, int nLength);
int Valid(void);
int Close(unsigned int waiting_thread_id);
//
void Clear(void);
char * GetStateName(typeTcpStates nState);
char * GetStateName(void) { return GetStateName(m_nState); }
int Export_Local_Address( void * socket_address_storage, unsigned int storage_size );
void SetConnection( unsigned long ip_address, unsigned short port);
int ChangeSocketState(typeTcpStates);
int StoreReceivedData(const unsigned char * pData, const unsigned int nLength);
int AbortReceive( int nStatus );
public: // Events
int OnCompleteUserCommand(int nStatus);
int OnConnect(int nStatus);
int OnAcceptIncomingConnection( int status );
int OnClose( int status );
int OnSendData(int status);
public:
CSocket * NextFree() { return m_NextFree; }
void NextFree( CSocket * s ) { m_NextFree = s; }
int ProcessIncomingConnection( CSocket *pListenSocket,const typeHeaderTCP *pTcpHeader, const typeIpPseudoHeader * pIpPseudoHeader);
int PutConnectionIntoEndOfChain();
bool RemoveConnectionFromChain();
private:
int GetControlBits(const typeHeaderTCP* pHeader) { return 0x003f & swap16(pHeader->nFlags); }
int GetDataOffest(const typeHeaderTCP* pHeader) { return swap16(pHeader->nFlags)>>12; }
private:
int SendPacket(const int nFlags, const unsigned char * pData, const unsigned int nLength);
int Export_Address( void * socket_address_storage, unsigned int storage_size );
int Import_Address( void * socket_address_storage, unsigned int storage_size );
private:
CSocket * GetPendingConnectionFromChain();
// ---------------- Added in 2010 :) --------------------------
ITransportLayer * GetTransport(void);
};
Посчитаем размер для 32-х битной архитектуры?
22 * sizeof(void*) + 1024 + 4 = 1116 байт на реализацию сокета.
Для 8 соединений достаточно 9 Кб. Но это без учёта буферов сетевой карты и буферов TCP и IP сервисов. Кстати, здесь большое поле для оптимизации и есть желание реализовать идею, подсмотренную в одной из версий для встраиваемых устройств, когда выделяется память сразу на весь ethernet или ppp фрейм, а протоколы только дописывают заголовки к данным. Т.ч. если заинтересуетесь, то будет стимул реализовать эту фичу.