|
|||||||
|
|
|
![]() |
|
|
Strumenti |
|
|
#1 |
|
Senior Member
Iscritto dal: Dec 2007
Città: Palestro
Messaggi: 1960
|
[C/C++] ottenere un istream* da un socket
Come da titolo..si può ottenere un istream* a partire da un socket? Se sì, qualcuno saprebbe dirmi come?
Grazie in anticipo! ps: si parla di Linux..non windows..ma in questo caso, non dovrebbe cambiare poi molto.. |
|
|
|
|
|
#2 | |
|
Senior Member
Iscritto dal: Oct 2005
Messaggi: 3306
|
Quote:
Dovresti farti una classe wrapper sulle funzionalità dei socket e a questa aggiungere gli operatori stream che si appoggiano su recv/recvfrom send/sendto. |
|
|
|
|
|
|
#3 |
|
Senior Member
Iscritto dal: Dec 2007
Città: Palestro
Messaggi: 1960
|
Stavo pensando anch'io ad una classe wrapper, ma purtroppo, devo dare in pasto l'istream ad uno scanner Flex, che accetta solo quel tipo di formato.. Grazie per la risposta!
|
|
|
|
|
|
#4 |
|
Senior Member
Iscritto dal: Oct 2006
Città: Roma
Messaggi: 1383
|
devi implementare uno streambuf che faccia I/O sul socket e poi costruire l'iostream al di sopra di esso. l'ho fatto anche io in passato, ecco il codice.
SocketBuffer.h: Codice:
#pragma once
#define SOCKET_INPUT_BUFFER_SIZE ((size_t)0x1000)
#define SOCKET_OUTPUT_BUFFER_SIZE ((size_t)0x1000)
class CSocketBuffer :
public streambuf
{
private:
SOCKET m_s;
char m_aInput[SOCKET_INPUT_BUFFER_SIZE];
char m_aOutput[SOCKET_OUTPUT_BUFFER_SIZE + 1];
private:
CSocketBuffer(const CSocketBuffer&);
CSocketBuffer &operator = (const CSocketBuffer&);
protected:
virtual int sync();
virtual int underflow();
virtual int overflow(int c = EOF);
public:
explicit CSocketBuffer(SOCKET s);
virtual ~CSocketBuffer();
string GetPeerName();
};
SocketBuffer.cpp: Codice:
#include <StdAfx.h>
#include <SocketBuffer.h>
CSocketBuffer::CSocketBuffer(const CSocketBuffer&)
{
}
CSocketBuffer &CSocketBuffer::operator = (const CSocketBuffer&)
{
return *this;
}
int CSocketBuffer::sync()
{
if (overflow() != EOF)
{
return 0;
}
else
{
return -1;
}
}
int CSocketBuffer::underflow()
{
ssize_t cbRead = ::recv(m_s, m_aInput, SOCKET_INPUT_BUFFER_SIZE, 0);
if (cbRead <= 0)
{
return EOF;
}
setg(m_aInput, m_aInput, m_aInput + cbRead);
return m_aInput[0];
}
int CSocketBuffer::overflow(int c)
{
size_t cbToWrite = pptr() - pbase();
if (c != EOF)
{
*pptr() = c;
cbToWrite++;
}
size_t cbWritten = 0;
while (cbWritten < cbToWrite)
{
ssize_t nResult = ::send(m_s, pbase() + cbWritten, cbToWrite - cbWritten, 0);
if (nResult <= 0)
{
return EOF;
}
cbWritten += nResult;
}
pbump(pbase() - pptr());
return 0;
}
CSocketBuffer::CSocketBuffer(SOCKET a_s) :
m_s(a_s)
{
setg(m_aInput, m_aInput, m_aInput);
setp(m_aOutput, m_aOutput + SOCKET_OUTPUT_BUFFER_SIZE);
}
CSocketBuffer::~CSocketBuffer()
{
sync();
int nResult = ::shutdown(m_s, SD_BOTH);
assert(!nResult);
nResult = ::closesocket(m_s);
assert(!nResult);
}
string CSocketBuffer::GetPeerName()
{
struct sockaddr_in sa;
int cbsa;
if (::getpeername(m_s, (struct sockaddr*)&sa, &cbsa) < 0)
{
cerr << "system error " << errno << " on getpeername" << endl;
throw false;
}
return ::inet_ntoa(sa.sin_addr);
}
__________________
3D Volley Demo (Facebook) | Reversi (Facebook) | Blockout (Facebook) | Puzzle15 (Facebook) Ultima modifica di fero86 : 19-02-2010 alle 02:34. |
|
|
|
|
|
#5 |
|
Senior Member
Iscritto dal: Dec 2007
Città: Palestro
Messaggi: 1960
|
Grazie mille, fre86, ma avrei ancora una domanda: per costruirci l'istream sopra questa..glielo passo nel costruttore di copia? qualcosa del tipo
streambuf buffer; istream *inputFile(&buffer);? Sempre sperando che lo scanner non richieda la fine del file, prima di ritornare i valori al parser..se no sono comunque nella c..ioccolata! |
|
|
|
|
|
#6 | ||
|
Senior Member
Iscritto dal: Oct 2006
Città: Roma
Messaggi: 1383
|
Quote:
Codice:
SOCKET s = ... ; CSocketBuffer Buffer(s); istream is(&Buffer); Quote:
|
||
|
|
|
|
|
#7 |
|
Senior Member
Iscritto dal: Oct 2006
Città: Roma
Messaggi: 1383
|
se usi la mia classe fai attenzione al fatto che il suo distruttore si occupa anche di chiudere il socket; non chiamare tu la closesocket, la chiama il distruttore.
|
|
|
|
|
|
#8 | |
|
Senior Member
Iscritto dal: Dec 2007
Città: Palestro
Messaggi: 1960
|
Quote:
(ps per il distruttore..no problem..c'ero arrivato! Almeno qui! |
|
|
|
|
|
| Strumenti | |
|
|
Tutti gli orari sono GMT +1. Ora sono le: 23:48.




















