CSocket
Třída
Odvozuje od CAsyncSocket
, dědí jeho zapouzdření rozhraní Windows Sockets API a představuje vyšší úroveň abstrakce než objektu CAsyncSocket
.
Syntaxe
class CSocket : public CAsyncSocket
Členové
Veřejné konstruktory
Název | Popis |
---|---|
CSocket::CSocket |
CSocket Vytvoří objekt. |
Veřejné metody
Název | Popis |
---|---|
CSocket::Attach |
SOCKET Připojí popisovač k objektuCSocket . |
CSocket::CancelBlockingCall |
Zruší blokující volání, které právě probíhá. |
CSocket::Create |
Vytvoří soket. |
CSocket::FromHandle |
Vrátí ukazatel na objekt vzhledem k CSocket popisovači SOCKET . |
CSocket::IsBlocking |
Určuje, jestli probíhá blokující volání. |
Chráněné metody
Název | Popis |
---|---|
CSocket::OnMessagePending |
Volání pro zpracování čekajících zpráv při čekání na dokončení blokujícího volání |
Poznámky
CSocket
pracuje s třídami CSocketFile
a CArchive
spravuje odesílání a přijímání dat.
Objekt CSocket
také poskytuje blokování, což je nezbytné pro synchronní provoz CArchive
. Blokující funkce, například Receive
, Send
, ReceiveFrom
, SendTo
a Accept
(všechny zděděné z CAsyncSocket
), nevrací WSAEWOULDBLOCK
chybu v CSocket
. Místo toho tyto funkce čekají na dokončení operace. Kromě toho se původní volání ukončí s chybou WSAEINTR, pokud CancelBlockingCall
je volána, zatímco jedna z těchto funkcí blokuje.
Chcete-li použít CSocket
objekt, zavolejte konstruktor a potom volání Create
vytvořit podkladový SOCKET
popisovač (typ SOCKET
). Výchozí parametry vytvoření soketu Create
streamu, ale pokud soket nepoužíváte s objektem CArchive
, můžete místo toho zadat parametr pro vytvoření soketu datagramu nebo vytvořit vazbu na konkrétní port pro vytvoření soketu serveru. Připojte se k klientskému soketu pomocí Connect
na straně klienta a Accept
na straně serveru. Pak vytvořte CSocketFile
objekt a přidružte ho k objektu CSocket
v konstruktoru CSocketFile
. Dále vytvořte CArchive
objekt pro odesílání a jeden pro příjem dat (podle potřeby) a pak je přidružte k objektu CSocketFile
v konstruktoru CArchive
. Po dokončení komunikace zničit CArchive
, CSocketFile
a CSocket
objekty. Datový SOCKET
typ je popsán v článku Windows Sockets: Background.
Při použití CArchive
s CSocketFile
a CSocket
, může dojít k situaci, kdy CSocket::Receive
vstoupí do smyčky (by PumpMessages(FD_READ)
) čekání na požadované množství bajtů. Je to proto, že sokety Windows umožňují pouze jedno volání recv na FD_READ
oznámení, ale CSocketFile
umožňují CSocket
více volání recv na každý FD_READ
. Pokud se zobrazí zpráva, FD_READ
že nejsou k dispozici žádná data ke čtení, aplikace přestane reagovat. Pokud nikdy nedostanete další FD_READ
, aplikace přestane komunikovat přes soket.
Tento problém můžete vyřešit následujícím způsobem. OnReceive
V metodě třídy soketů volejte CAsyncSocket::IOCtl(FIONREAD, ...)
před voláním Serialize
metody třídy zpráv, když očekávaná data, která se mají číst ze soketu, překročí velikost jednoho paketu TCP (maximální přenosová jednotka síťového média, obvykle nejméně 1096 bajtů). Pokud je velikost dostupných dat menší, než je potřeba, počkejte na přijetí všech dat a teprve pak spusťte operaci čtení.
V následujícím příkladu je přibližný počet bajtů, m_dwExpected
které uživatel očekává. Předpokládá se, že ho deklarujete jinde ve svém kódu.
void CChatSocket::OnReceive(int nErrorCode)
{
CSocket::OnReceive(nErrorCode);
DWORD dwReceived;
if (IOCtl(FIONREAD, &dwReceived))
{
if (dwReceived >= m_dwExpected) // Process only if you have enough data
m_pDoc->ProcessPendingRead();
}
else
{
// Error handling here
}
}
Poznámka:
Při použití soketů MFC v sekundárních vláknech v staticky propojené aplikaci MFC je nutné volat AfxSocketInit
v každém vlákně, které používá sokety k inicializaci knihoven soketů. Ve výchozím nastavení AfxSocketInit
se volá pouze v primárním vlákně.
Další informace naleznete v tématu Windows Sockets in MFC, Windows Sockets: Using Sockets with Archives, Windows Sockets: How Sockets with Archives Work, Windows Sockets: Sequence of Operations, Windows Sockets: Example of Sockets Using Archives.
Hierarchie dědičnosti
CSocket
Požadavky
Záhlaví: afxsock.h
CSocket::Attach
Voláním této členské funkce připojíte hSocket
popisovač k objektu CSocket
.
BOOL Attach(SOCKET hSocket);
Parametry
hSocket
Obsahuje popisovač soketu.
Návratová hodnota
Nenulové, pokud je funkce úspěšná.
Poznámky
Popisovač SOCKET
je uložen v datovém členu objektu m_hSocket
.
Další informace naleznete v tématu Windows Sockets: Použití soketů s archivy.
Příklad
class CSockThread : public CWinThread
{
public:
SOCKET m_hConnected;
protected:
CChatSocket m_sConnected;
// remainder of class declaration omitted.
BOOL CSockThread::InitInstance()
{
// Attach the socket object to the socket handle
// in the context of this thread.
m_sConnected.Attach(m_hConnected);
m_hConnected = NULL;
return TRUE;
}
// This listening socket has been constructed
// in the primary thread.
void CListeningSocket::OnAccept(int nErrorCode)
{
UNREFERENCED_PARAMETER(nErrorCode);
// This CSocket object is used just temporarily
// to accept the incoming connection.
CSocket sConnected;
Accept(sConnected);
// Start the other thread.
CSockThread *pSockThread = (CSockThread*)AfxBeginThread(
RUNTIME_CLASS(CSockThread), THREAD_PRIORITY_NORMAL, 0, CREATE_SUSPENDED);
if (NULL != pSockThread)
{
// Detach the newly accepted socket and save
// the SOCKET handle in our new thread object.
// After detaching it, it should no longer be
// used in the context of this thread.
pSockThread->m_hConnected = sConnected.Detach();
pSockThread->ResumeThread();
}
}
CSocket::CancelBlockingCall
Voláním této členské funkce zrušíte probíhající blokující volání.
void CancelBlockingCall();
Poznámky
Tato funkce zruší všechny neuhrazené blokující operace pro tento soket. Původní blokující volání se ukončí co nejdříve s chybou WSAEINTR
.
V případě blokující Connect
operace ukončí implementace rozhraní Windows Sockets blokující volání co nejdříve, ale nemusí být možné uvolnit prostředky soketu, dokud se připojení nedokončí (a poté se resetuje) nebo vyprší časový limit. To bude pravděpodobně patrné pouze v případě, že se aplikace okamžitě pokusí otevřít nový soket (pokud nejsou k dispozici žádné sokety) nebo se připojit ke stejnému partnerskému uzlu.
Zrušení jakékoli jiné operace, než Accept
může nechat soket v neurčitém stavu. Pokud aplikace zruší blokující operaci na soketu, jediná operace, kterou aplikace může záviset na schopnosti provádět na soketu, je volání Close
, i když jiné operace mohou fungovat na některých implementacích Windows Sockets. Pokud si přejete maximální přenositelnost aplikace, musíte být opatrní, abyste nezávisli na provádění operací po zrušení.
Další informace naleznete v tématu Windows Sockets: Použití soketů s archivy.
CSocket::Create
Create
Volání členské funkce po vytvoření objektu soketu pro vytvoření soketu Systému Windows a jeho připojení.
BOOL Create(
UINT nSocketPort = 0,
int nSocketType = SOCK_STREAM,
LPCTSTR lpszSocketAddress = NULL);
Parametry
nSocketPort
Konkrétní port, který se má použít se soketem, nebo 0, pokud chcete, aby knihovna MFC vybrali port.
nSocketType
SOCK_STREAM
nebo SOCK_DGRAM
.
lpszSocketAddress
Ukazatel na řetězec obsahující síťovou adresu připojeného soketu, tečkované číslo, například 128.56.22.8. Předání řetězce NULL pro tento parametr označuje, že CSocket
instance by měla naslouchat aktivitě klienta ve všech síťových rozhraních.
Návratová hodnota
Nenulové, pokud je funkce úspěšná; jinak 0 a konkrétní kód chyby lze načíst voláním GetLastError
.
Poznámky
Create
potom volání Bind
pro vazbu soketu na zadanou adresu. Podporují se následující typy soketů:
SOCK_STREAM
Poskytuje sekvencované, spolehlivé obousměrné bajtové datové proudy založené na připojení. Používá protokol TCP (Transmission Control Protocol) pro řadu internetových adres.SOCK_DGRAM
Podporuje datagramy, které jsou bez připojení, nespolehlivé vyrovnávací paměti pevné (obvykle malé) maximální délky. Používá protokol UDP (User Datagram Protocol) pro řadu internetových adres. Chcete-li použít tuto možnost, nesmíte použít soket s objektemCArchive
.Poznámka:
Členová
Accept
funkce jako parametr přebírá odkaz na nový prázdnýCSocket
objekt. Tento objekt je nutné sestavit před volánímAccept
. Mějte na paměti, že pokud tento objekt soketu přestane být obor, připojení se zavře. NevolejteCreate
pro tento nový objekt soketu.
Další informace o soketech datových proudů a datovýchgramů najdete v článcích Windows Sockets: Background, Windows Sockets: Ports and Sockets Addresses a Windows Sockets: Using Sockets with Archives.
CSocket::CSocket
CSocket
Vytvoří objekt.
CSocket();
Poznámky
Po konstrukci je nutné volat člena Create
funkce.
Další informace naleznete v tématu Windows Sockets: Použití soketů s archivy.
CSocket::FromHandle
Vrátí ukazatel na CSocket
objekt.
static CSocket* PASCAL FromHandle(SOCKET hSocket);
Parametry
hSocket
Obsahuje popisovač soketu.
Návratová hodnota
Ukazatel na objekt nebo NULL
pokud není k objektu CSocket
připojen hSocket
žádný CSocket
objekt .
Poznámky
Při zadání SOCKET
popisovače, pokud CSocket
objekt není připojen k popisovači, členské funkce vrátí NULL
a nevytvoří dočasný objekt.
Další informace naleznete v tématu Windows Sockets: Použití soketů s archivy.
CSocket::IsBlocking
Voláním této členské funkce určíte, jestli probíhá blokující volání.
BOOL IsBlocking();
Návratová hodnota
Nenulové, pokud soket blokuje; jinak 0.
Poznámky
Další informace naleznete v tématu Windows Sockets: Použití soketů s archivy.
CSocket::OnMessagePending
Přepište tuto členovu funkci tak, aby hledala konkrétní zprávy z Windows a reagovala na ně v soketu.
virtual BOOL OnMessagePending();
Návratová hodnota
Nenulové, pokud byla zpráva zpracována; jinak 0.
Poznámky
Jedná se o pokročilý přepis.
Rozhraní volá OnMessagePending
, zatímco soket pumpuje zprávy Systému Windows, abyste získali příležitost vypořádat se se zprávami, které jsou pro vaši aplikaci zajímavé. Příklady použití OnMessagePending
naleznete v článku Windows Sockets: Odvození z tříd soketů.
Další informace naleznete v tématu Windows Sockets: Použití soketů s archivy.
Viz také
CAsyncSocket
Třída
Graf hierarchie
CAsyncSocket
Třída
CSocketFile
Třída