Számítógép-hálózatok: 4. Labor
TCP kliens A gyakorlat célja: TCP kliens alkalmazás írásának az elsajátítása TCP protokoll tulajdonságainak a tanulmányozása Elméleti bevezető: TCP tulajdonságai: A TCP az UDP-vel ellentétben egy összeköttés alapú (STREAMING) protokoll. Ahoz, hogy adatot tudjak küldeni egy másik alkalmazásnak (komunikációs végpontnak - socketnek) kapcsolatott kell kiépítsek valamint, ha befejeztem a kommunikációt ezt a kapcsolatott bontani kell a kapcsolatot. A TCP-nek emelett még más szolgáltatásai is vannak ilyen például a megbizható adatátvitel. A megbizható azt jelenti, hogy az adatot vagy sikeresen kézbesítve van a cél gépnek vagy egy hibaüzenetet kapok. Viszont a TCP nem biztosítja az üzenet határokat, hanem adatfolyammal dolgozik. TCP kilens alkalmazás:
Számítógép-hálózatok: 4. Labor
Amint a fenti ábrából is kiderül az UDP klienshez képest a TCP kliens egyedül a kapcsolódást biztosító Connect függvény hozzáadásával bővül. int connect( __in SOCKET s, __in const struct sockaddr *name, __in int namelen );
s [in]
Egy socket azonósító, amely egy kapcsolat nélküli socketet azonósít. name [in]
Egy a sockaddr struktúra típusú mutató, amely tartalmazza a cél szerver ip címét és a portotját. namelen [in]
A sockaddr struktúra mérete. A Connect függvény sikeres kapcsolódás esetén 0-t térít vissza. Hiba estén SOCKET_ERROR-t térít vissza, amelynek a kódját a WSAGetLastError- függvény meghívásával kaphatjuk meg.
Feladat: 1. Valósítsatok meg egy TCP alapú visszhang klienst. Példaprogram: #include <stdio.h> #include <string.h> #include "winsock2.h" #pragma comment(lib, "ws2_32.lib") void main() { // visszatéritési érték tárolásához int iResult; //---------------------// Inicializálja a Winsock könyvtárat WSADATA wsaData; iResult = WSAStartup(MAKEWORD(2,2), &wsaData);
Számítógép-hálózatok: 4. Labor if (iResult != NO_ERROR) printf("Hiba a WSAStartup() –nál\n");
//---------------------// Létrehozunk egy SOCKET-et amelyik a szerverhez kapcsolódik SOCKET KlientSocket; //https://msdn.microsoft.com/enus/library/windows/desktop/ms737625%28v=vs.85%29.aspx KlientSocket = socket(AF_INET, , ); if (KlientSocket == INVALID_SOCKET) { printf("Hiba a socket inicializálásánál a következő hibakóddal: %ld\n", WSAGetLastError()); // WSACleanup befejezi a Windows Sockets működését minden szálban!!!! WSACleanup(); return; } //---------------------// A sockaddr_in struktúra meghatározza a cím családot, // Az IP címet és a portot amihez kapcslódnia kell int Port=; char IP[10]="..."; sockaddr_in ServerAddr; int AddrLen=sizeof(ServerAddr); ServerAddr.sin_family = AF_INET; ServerAddr.sin_addr.s_addr = inet_addr( IP ); ServerAddr.sin_port = htons( Port ); //---------------------// A kapcsolat felépítése. if ( connect(, (SOCKADDR*) &, ) == SOCKET_ERROR) { printf( "Hiba a kapcsolódásnál a következő hibakóddal: %ld\n", WSAGetLastError() ); // WSACleanup befejezi a Windows Sockets működését minden szálban!!!! WSACleanup(); return; } //---------------------// Küldés itt az idő szerver esetében nem kell /* const int SendBufLen=1024; char SendBuf[SendBufLen]; int DataLen; strcpy_s(SendBuf,"Bármi lehet ez"); DataLen=strlen(SendBuf)+1; iResult = send( KlientSocket, SendBuf, DataLen, 0 ); if (iResult == SOCKET_ERROR) {
Számítógép-hálózatok: 4. Labor printf("Hiba a küldésnél a következő hibakóddal: %d\n", WSAGetLastError()); closesocket(KlientSocket); // WSACleanup befejezi a Windows Sockets működését minden szálban!!!! WSACleanup(); return; } //itt le kell elenőrizni hogy elment-e az összes adat */ //-----------------------------------------------------// az idő fogadása const int RecBufLen=1024; char RecBuf[RecBufLen]; iResult = recv( KlientSocket, RecBuf, RecBufLen-1, 0 ); //Ha hiba történt a fogadásnál if (iResult == SOCKET_ERROR) { printf("Hiba a fogadásnál a következő hibakóddal: %d\n", WSAGetLastError()); closesocket(KlientSocket); // WSACleanup befejezi a Windows Sockets működését minden szálban!!!! WSACleanup(); return; } //ha lezátuk valhol a socketet if (iResult == 0) { return; } //kiiratjuk az eredményt RecBuf[iResult]='\0'; printf("%s \n",RecBuf);
//Kapcsolat bontása iResult = shutdown(KlientSocket, SD_SEND); //vagy lehet használni a //iResult = closesocket(KlientSocket); //minden befejezödött felszabadítom a // WSACleanup befejezi a Windows Sockets működését minden szálban!!!! WSACleanup(); return; }
Kérdések: 1. Mi a különbség a send és a sendto valamint a recv és recvfrom között? 2. Az alkalmazás kapcsolatában milyen állapotokat tudsz meghatározni Netstattal 3. Mit csinál a shutdown függvény?
Számítógép-hálózatok: 4. Labor Könyvészet: [1]. A. Tanenbaum : Számítógéphálózatok. Bp., Panem Könyvkiad ó, 1999. [2]. http://msdn.microsoft.com/en-us/library/ms741416(VS.85).aspx