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;
}