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:
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] name [in] namelen [in] Egy socket azonósító, amely egy kapcsolat nélküli socketet azonósít. Egy a sockaddr struktúra típusú mutató, amely tartalmazza a cél szerver ip címét és a portotját. 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);
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", // 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() ); // 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)
*/ printf("hiba a küldésnél a következő hibakóddal: %d\n", closesocket(klientsocket); // WSACleanup befejezi a Windows Sockets működését minden szálban!!!! //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", closesocket(klientsocket); //ha lezátuk valhol a socketet if (iresult == 0) //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 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?
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