|
|
|
![]() |
|
Strumenti |
![]() |
#1 |
Senior Member
Iscritto dal: Dec 2007
Città: Palestro
Messaggi: 1957
|
[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: 1957
|
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 01:34. |
![]() |
![]() |
![]() |
#5 |
Senior Member
Iscritto dal: Dec 2007
Città: Palestro
Messaggi: 1957
|
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: 1957
|
Quote:
(ps per il distruttore..no problem..c'ero arrivato! Almeno qui! ![]() |
|
![]() |
![]() |
![]() |
Strumenti | |
|
|
Tutti gli orari sono GMT +1. Ora sono le: 15:47.