TCP server, TCP klient v Linuxu – C / C++ – Fórum – Programujte.com
 x   TIP: Přetáhni ikonu na hlavní panel pro připnutí webu

TCP server, TCP klient v Linuxu – C / C++ – Fórum – Programujte.comTCP server, TCP klient v Linuxu – C / C++ – Fórum – Programujte.com

 

Toto vlákno bylo označeno za vyřešené — příspěvek s řešením.
kocourOggy0
Newbie
2. 6. 2016   #1
-
0
-

Zdravim,
prochazim si tutorial ze stranek builder.cz ohledne soketu v Linuxu. Konkretne priklady na TCP server a TCP klienta (viz ukazky).
Kdyz si priklady zkousim na localhostu (127.0.0.1). Vse funguje dobre (klient odesle na server string "Ahoj" a server mu na oplatku posle string "Zdravim"). Problem nastava kdyz jsem se pokusil spojeni provest mezi dvema ruznymi pocitaci. Ukazkove priklady jsem spustil takto:
    server.out "6666"  // (cislo portu)

    client.out "78.45.112.101" "6666" (ip adresa serveru, cislo portu)

Potiz je zrejme v tom, ze desktop (server) i laptop (klient) maji stejne IP adresy. Desktop je pripojeny na sitovy kabel k modemu a laptop je naopak pripojeny k modemu pres wi-fi. Nabizi se otazka, co tedy napsat jako IP adresu, kdyz je jak pro server tak i klienta stejna? Nanestesti sitemi jsem zcela nepoliben... je mozne ze zadavam treba spatnou IP adresu? ( pouzil jsem stranky mojeip.cz )

#include <iostream>
#include <string>
#include <cstring>
#include <cstdlib>
#include <unistd.h>
#include <netdb.h>
#include <netinet/in.h>
#include <sys/types.h>
#include <sys/socket.h>

#define BUFSIZE 1000

/*
KLIENT
*/

using namespace std;

int main(int argc, char *argv[])
{
    string text("Ahoj\n");      // Odesílaný a přijímaný text
    hostent *host;              // Vzdálený počítač;
    sockaddr_in serverSock;     // Vzdálený "konec potrubí"
    int mySocket;               // Soket
    int port;                   // Číslo portu
    char buf[BUFSIZE];          // Přijímací buffer
    int size;                   // Počet přijatých a odeslaných bytů
    if (argc != 3)
    {
        cerr << "Syntaxe:\n\t" << argv[0]
                  << " " << "adresa port" << endl;
        return -1;
    }
    port = atoi(argv[2]);
    // Zjistíme info o vzdáleném počítači
    if ((host = gethostbyname(argv[1])) == NULL)
    {
        cerr << "Špatná adresa" << endl;
        return -1;
    }
    // Vytvoříme soket
    if ((mySocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)) == -1)
    {
        cerr << "Nelze vytvořit soket" << endl;
        return -1;
    }
    // Zaplníme strukturu sockaddr_in
    // 1) Rodina protokolů
    serverSock.sin_family = AF_INET;
    // 2) Číslo portu, ke kterému se připojíme
    serverSock.sin_port = htons(port);
    // 3) Nastavení IP adresy, ke které se připojíme
    memcpy(&(serverSock.sin_addr), host->h_addr, host->h_length);
    // Připojení soketu
    if (connect(mySocket, (sockaddr *)&serverSock, sizeof(serverSock)) == -1)
    {
        cerr << "Nelze navázat spojení" << endl;
        return -1;
    }
    // Odeslání dat
    if ((size = send(mySocket, text.c_str(), text.size() + 1, 0)) == -1)
    {
        cerr << "Problém s odesláním dat" << endl;
        return -1;
    }
    cout << "Odesláno " << size << endl;
    // Příjem dat
    text = "";
    while ((size = recv(mySocket, buf, BUFSIZE, 0)) != -1) 
    {        
        cout << "Přijato " << size << endl;
        text += buf;
        if (size == 0) break;
    }
    // Uzavřu spojení
    close(mySocket);
    cout <<  endl << text << endl;
    return 0;
}
#include <iostream>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <string>
#include <cstring>
#include <cstdlib>


#define BUFSIZE 1000

/*
SERVER
*/

using namespace std;

int main(int argc, char *argv[])
{
   std::string text;             // Přijímaný text
   sockaddr_in sockName;         // "Jméno" portu
   sockaddr_in clientInfo;       // Klient, který se připojil 
   int mainSocket;               // Soket
   int port;                     // Číslo portu
   char buf[BUFSIZE];            // Přijímací buffer
   int size;                     // Počet přijatých a odeslaných bytů
   socklen_t addrlen;            // Velikost adresy vzdáleného počítače
   int count = 0;                // Počet připojení

   if (argc != 2)
   {
     cerr << "Syntaxe:\n\t" << argv[0]
	  << " " << "port" << endl;
     return -1;
   }
   port = atoi(argv[1]);
   // Vytvoříme soket - viz minulý díl
   if ((mainSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)) == -1)
   {
     cerr << "Nelze vytvořit soket" << endl;
     return -1;
   }
   // Zaplníme strukturu sockaddr_in
   // 1) Rodina protokolů
   sockName.sin_family = AF_INET;
   // 2) Číslo portu, na kterém čekáme
   sockName.sin_port = htons(port);
   // 3) Nastavení IP adresy lokální síťové karty, přes kterou je možno se
   //    připojit. Nastavíme možnost připojit se odkudkoliv. 
   sockName.sin_addr.s_addr = INADDR_ANY;
   // přiřadíme soketu jméno
   if (bind(mainSocket, (sockaddr *)&sockName, sizeof(sockName)) == -1)
   {
     cerr << "Problém s pojmenováním soketu." << endl;
     return -1;
   }
   // Vytvoříme frontu požadavků na spojení. 
   // Vytvoříme frontu maximální velikosti 10 požadavků.
   if (listen(mainSocket, 10) == -1)
   {
     cerr << "Problém s vytvořením fronty" << endl;
     return -1;
   }
   do
   {
     // Poznačím si velikost struktury clientInfo.
     // Předám to funkci accept. 
     addrlen = sizeof(clientInfo);
     // Vyberu z fronty požadavek na spojení.
     // "client" je nový soket spojující klienta se serverem.
     int client = accept(mainSocket, (sockaddr*)&clientInfo, &addrlen);
     int totalSize = 0;
     if (client == -1)
     {
       cerr << "Problém s přijetím spojeni" <<endl;
       return -1;
     }
     // Zjistím IP klienta.
     cout << "Někdo se připojil z adresy: " 
	  << inet_ntoa((in_addr)clientInfo.sin_addr) << endl;
     // Přijmu data. Ke komunikaci s klientem používám soket "client"
     text = "";
     // Přijmeme maximálně 6 bytový pozdrav. 
     while (totalSize != 6)
     {
       if ((size = recv(client, buf, BUFSIZE - 1, 0)) == -1)
       {
	 cerr << "Problém s přijetím dat." << endl;
	 return -1;
       }
       cout << "Přijato: " << size << endl;
       totalSize += size;
       text += buf;
     }
     cout << text;
     // Odešlu pozdrav
     if ((size = send(client, "Nazdar\n", 8, 0)) == -1)
     {
       cerr << "Problém s odesláním dat" << endl;
       return -1;
     }
     cout << "Odesláno: " << size << endl;
     // Uzavřu spojení s klientem
     close(client);
   }
   while (++count != 3);
   cout << "Končím" << endl;
   close(mainSocket);
   return 0;
}
Nahlásit jako SPAM
IP: 78.45.112.–
Věčný začátečník nejen v Pythonu.
NeregistrovanyHookyns
~ Anonymní uživatel
62 příspěvků
2. 6. 2016   #2
-
0
-

Pochybuji, že mají obě zařízení stejnou IP adresu. I když jsou připojena ke stejnému modemu (který má svou IP), tak každé zařízení pak musí mít svou vlastní IP adresu v lokální síti.

Nahlásit jako SPAM
IP: 77.95.192.–
kocourOggy0
Newbie
2. 6. 2016   #3
-
0
-

#2 NeregistrovanyHookyns
Aha, takze v tom pripade IP adresu zjistit jinou cestou nez pres stranky mojeip.cz

Nahlásit jako SPAM
IP: 78.45.112.–
Věčný začátečník nejen v Pythonu.
NeregistrovanyHookyns
~ Anonymní uživatel
62 příspěvků
2. 6. 2016   #4
-
+1
-
Zajímavé

A dodatek. Pokud máš veřejnou IP a k té se snažíš připojit, tak musíš mít zase správně nastavený port forwarding v modemu/routeru. Navíc musíš mít povolenou komunikaci na daném portu ve firewallu.

Nahlásit jako SPAM
IP: 77.95.192.–
Řešení
NeregistrovanyHookyns
~ Anonymní uživatel
62 příspěvků
2. 6. 2016   #5
-
+1
-
Zajímavé
Vyřešeno Nejlepší odpověď

Ano. Pokud jsi na windows, tak v příkazovém řádku příkaz ipconfig, pokud na linuxu, tak ifconfig eth0, př ifconfig wlan0 nebo příslušné jméno adaptéru.

Nahlásit jako SPAM
IP: 77.95.192.–
kocourOggy0
Newbie
2. 6. 2016   #6
-
0
-

#5 NeregistrovanyHookyns
To uz zni trochu slozite... navic ja provozuju Linux pouze ve Virtualboxu, nicmene internet zdarne funguje. Prikazovy radek ve Windows jak na desktopu tak i laptopu ukazuje jiz dve ruzne IPv4 adresy, dokonce ukazuje IPv4 z VirtualBoxu, s podivem ale prikazovy radek na Windows ukazuje tyhle dve adresy ohledne VirtualBoxu na desktopu a laptopu stejne!

Kdyz si vezmu jenom desktop tak ifconfig z terminalu v Linuxu zase vyhazuje naprosto odlisne adresy...Windows mi na desktopu zobrazuji adresu z virtualboxu jako 192.168...Linuxy na desktopu zase 10.0.2.15 viz obrazek

Připojen obrázek.

Připojen obrázek.

Nahlásit jako SPAM
IP: 78.45.112.–
Věčný začátečník nejen v Pythonu.
kocourOggy0
Newbie
2. 6. 2016   #7
-
0
-

#6 kocourOggy
Jeste se zeptam... kdyz mi kod funguje na localhostu v ramci jednoho pocitace, mam zaruku, ze mi kod bude fungovat i v ramci dvou ruznych pocitacu (pokud bych mel samozrejme znalost na to si rozumne nastavit porty a IP adresu)? Jak jsem psal na localhostu kod funguje bez problemu, ale chtel jsem si to jeste zkusit spustit i mimo jeden pocitac. Nicmene je-li zarukou funkcnosti programu i localhost, tak zkouset to mezi dvema stroji nebude v tuhle chvili asi prilis dulezite.

Nahlásit jako SPAM
IP: 78.45.112.–
Věčný začátečník nejen v Pythonu.
NeregistrovanyHookyns
~ Anonymní uživatel
62 příspěvků
2. 6. 2016   #8
-
0
-

Pokud to funguje na jednom zařízení, tak by to mělo fungovat i v síti mezi různými zařízeními, pokud budou tedy IP adresy správně nastavené.

S virtualem jsem měl vždy problém, co se sítí týče, takže zde bych nechal radu na někom jiném.

Každopádně v nastavení té virtuálky je možné nastavit i síť. Mělo by jít nastavit i sdílení adaptéru, což by bylo pro tebe asi nejlepší. Pokud se nepletu, tak virtualbox si normálně vytvoří virtuální adaptér a vytvoří pak mezi OS a virtualizovaným OS vlastní síť, což ti znemožní komunikaci s virtualkou z jiného PC. Sdílení adaptéru by to mělo umožnit. Ale jak říkám, v tomhle jsem spíše laik.

Nahlásit jako SPAM
IP: 77.95.192.–
kocourOggy0
Newbie
2. 6. 2016   #9
-
0
-

#8 NeregistrovanyHookyns
Dekuju za reakce! :) Aspon uz vim, ze to neni tak jednoduche jak jsem si se svym naivnim pohledem myslel.

Nahlásit jako SPAM
IP: 78.45.112.–
Věčný začátečník nejen v Pythonu.
Zjistit počet nových příspěvků

Přidej příspěvek

Toto téma je starší jak čtvrt roku – přidej svůj příspěvek jen tehdy, máš-li k tématu opravdu co říct!

Ano, opravdu chci reagovat → zobrazí formulář pro přidání příspěvku

×Vložení zdrojáku

×Vložení obrázku

Vložit URL obrázku Vybrat obrázek na disku
Vlož URL adresu obrázku:
Klikni a vyber obrázek z počítače:

×Vložení videa

Aktuálně jsou podporována videa ze serverů YouTube, Vimeo a Dailymotion.
×
 
Podporujeme Gravatara.
Zadej URL adresu Avatara (40 x 40 px) nebo emailovou adresu pro použití Gravatara.
Email nikam neukládáme, po získání Gravatara je zahozen.
-
Pravidla pro psaní příspěvků, používej diakritiku. ENTER pro nový odstavec, SHIFT + ENTER pro nový řádek.
Sledovat nové příspěvky (pouze pro přihlášené)
Sleduj vlákno a v případě přidání nového příspěvku o tom budeš vědět mezi prvními.
Reaguješ na příspěvek:

Uživatelé prohlížející si toto vlákno

Uživatelé on-line: 0 registrovaných, 103 hostů

Podobná vlákna

TCP server + multi-client — založil ingiraxo

TCP Socket Server Java — založil wiston

Tcp/Ip C++ — založil Kenvelo

TCP — založil Petr

Moderátoři diskuze

 

Hostujeme u Českého hostingu       ISSN 1801-1586       ⇡ Nahoru Webtea.cz logo © 20032024 Programujte.com
Zasadilo a pěstuje Webtea.cz, šéfredaktor Lukáš Churý