[mfc] wstrzymywanie watka

0

Mam sobie funckje (program pisany za pomoca MFC), ktora jest uruchomiona w osobnym watku, ma ona za zadanie czekac az cos przyjdzie od klienta (bo to jest serwer) i reagowac na to przez caly czas pracy klienta, zrobilem to tak:

CSocketFile socketfile(soc); //soc to jest gniazdo na kotrym 'siedzi' klient
CArchiwe rcv(sockfile;CArchiwe::load)
CPakiet pkt;  // CPakiet to jest moja klasa do przesylu daych, 
while (/*tu warunek do kiedy ma pracowac*/) {
   pkt.Serialize(rcv);
   // i tu sie bawie z odebranymi danymi
}

I teraz jest taki problem ze ten watek musi caly czas sprawdzac czy cos nie przyszlo do gniazda soc, ale jesli robie to tak jak wyzej to przy linii pkt.Serialize jesli nic nie przyszlo to wywala Runtime Error. Jest jakis sposob zeby sprawdzic czy cos nie przyszlo do gniazda? Albo zeby wstrzymac watek do czasu az cos do tego gniazda nie przyjdzie?

0

Kurna klajter, poczytać o programowaniu socketów wreszcie i o MFC...
CAsyncSocket jest w MFC, może nie będziesz musiał mordować w taki sposób wątków ;-P W CSocket też masz OnReceive(), itp.

0
marcinEc napisał(a)

Kurna klajter, poczytać o programowaniu socketów wreszcie i o MFC...

Czytam, co tylko znajde na ten temat to czytam...

CAsyncSocket jest w MFC, może nie będziesz musiał mordować w taki sposób wątków ;-P W CSocket też masz OnReceive(), itp.

Ze jest OnReceive to wiem, tylko wlasnie mi to nie dziala, znaczy 'normalnie' mi dziala, ale jak w watku dam np. while(1); co by sie mi nie skonczyl zaraz po rozpoczeciu to socket nie wywoluje ww metody po przyjciu danych i w tym wlasnie tkiw moj problem.. Nie wiem, jak mozesz/chce Ci sie/itd to zapodaj moze jakis prosty kod jakbys Ty to zrobil bo ja juz wymiekam...</quote>

0

No to po co ci te wątki?? Robisz klasę dziedziczącą po CSocket, implementujesz OnReceive() i tyle.

To się robi przez Class Wizarda, ale w kodzie masz:

class CClientSocket : public CSocket
{
// Attributes
public:
	CSocketFile *m_pFile;
	CArchive *m_pIn;
	CArchive *m_pOut;
	CString m_sName;
	CDiceDlg *m_pDlg;
// Operations
public:
	CClientSocket();
	virtual ~CClientSocket();
// Overrides
public:
	BOOL Connect(LPCTSTR lpszHostAddress, UINT nHostPort);
	void Init();
	// ClassWizard generated virtual function overrides
	//{{AFX_VIRTUAL(CClientSocket)
	public:
	virtual void OnReceive(int nErrorCode);
	virtual void OnClose(int nErrorCode);
	//}}AFX_VIRTUAL

	// Generated message map functions
	//{{AFX_MSG(CClientSocket)
		// NOTE - the ClassWizard will add and remove member functions here.
	//}}AFX_MSG

// Implementation
protected:
};

Implementacja:

CClientSocket::CClientSocket()
{
	m_pFile = NULL;
	m_pIn = NULL;
	m_pOut = NULL;
	m_pDlg = NULL;
}

CClientSocket::~CClientSocket()
{
	delete m_pOut;
	delete m_pIn;
	delete m_pFile;
}
// Do not edit the following lines, which are needed by ClassWizard.
#if 0
BEGIN_MESSAGE_MAP(CClientSocket, CSocket)
	//{{AFX_MSG_MAP(CClientSocket)
	//}}AFX_MSG_MAP
END_MESSAGE_MAP()
#endif	// 0

/////////////////////////////////////////////////////////////////////////////
// CClientSocket member functions
BOOL CClientSocket::Connect(LPCTSTR lpszHostAddress, UINT nHostPort)
{
	BOOL bRet = CSocket::Connect(lpszHostAddress, nHostPort);
	if (bRet) {
		m_pFile = new CSocketFile(this);
		m_pIn = new CArchive(m_pFile, CArchive::load);
		m_pOut = new CArchive(m_pFile, CArchive::store);
	}
	return bRet;
}
void CClientSocket::Init()
{
	m_pFile = new CSocketFile(this);
	m_pIn = new CArchive(m_pFile, CArchive::load);
	m_pOut = new CArchive(m_pFile, CArchive::store);
}
void CClientSocket::OnReceive(int nErrorCode) 
{
	CSocket::OnReceive(nErrorCode);
	if (m_pDlg)
		m_pDlg->OnReceiveData(this);
}
void CClientSocket::OnClose(int nErrorCode) 
{
	CSocket::OnClose(nErrorCode);
	if (m_pDlg)
		m_pDlg->OnCloseConnection(this);
}

W programie przechowujesz listę socketów (czyli np. CPtrList z CClientSocket)

OnReceiveData:

// Funkcja wywolywana w momencie otrzymania nowych danych.
void CxxxDlg::OnReceiveData(CClientSocket *pSocket)
{
	CString s;
	do 
	{
		pSocket->m_pIn->ReadString(s);
		if (GetCommand(s) == "TEXT") 
		{
			// Zostala otrzymana komenda 'TEXT',
			// wyswietlenie informacji w oknie z chatem.
			ChatAddLine(GetArgs(s));
			if (m_pServer)
				continue;
			// Jesli program jest serwerem, to przeslanie informacji
			// do pozostalych graczy
			SendToAllPlayers(s + "\n");
			continue;
		}
		if (GetCommand(s) == "START") {
			// Zostala otrzymana komenda 'START', rozpoczecie rozgrywki
			SetNames(GetArgs(s));
			continue;
		}
		if (GetCommand(s) == "END") 
		{
			// Zostala otrzymana komenda 'END', zakonczenie rozgrywki
			MessageBox("Partiŕ wygral: " + GetArgs(s), "Koťci");
			continue;
		}
    // ... itp.
		}
	} while (!pSocket->m_pIn->IsBufferEmpty());
// !! to jest właśnie obsługa TCP, odczytać WSZYSTKIE dane, czyli dopóki bufor nie jest pusty
}

Mam nadzieję, że coś to pomoże, albo mazury ;)

1 użytkowników online, w tym zalogowanych: 0, gości: 1