Pontifícia Universidade Católica do Rio Grande do Sul – Pucrs

Aluno: Roberto Benderrbender@ee.pucrs.br

Apresentação de Programação de Periféricos

 

Acesso a periférico remoto via internet

 

Protocolo TCP/IP

TCP:Transmission Control Protocol
IP: Internet Protocol

*      História

*      Backbone

*      Endereçamento

*      Transmissão

*    Portas de Comunicão

 

Sockets

Na camada de Transporte do modelo TCP/IP existem dispositivos denominados Portas, que nada tem a ver com COM's ou LPT's. Imagine um painel, cheio de tomadas, aonde cada tomada fosse uma porta. Cada porta dessa recebe um numero, que fica associado a um serviço. Por exemplo, para o serviço de HTTP, utilizamos a porta 80, para o serviço de POP3(Recebimento de e-mails) usamos a porta 110, e assim por diante. Estas portas permitem o estabelecimento de um "circuito virtual", o que e realmente necessário para a comunicação na Internet. Agora, imagine que você carregou o seu browser e este passou a fazer uso da sua porta 80. A "tomada" da porta 80 ficou então ocupada. Tecnicamente não seria possível carregar outro browser, ja que para HTTP precisamos da porta 80. Essa impossibilidade foi ultrapassada através de um sistema chamado Sockets. Com esse método, quando um programa precisa criar uma conexão com uma determinada porta, ele tem que criar um Socket conectado a ela. Sockets são representações da conexão de um aplicativo com uma porta. Com eles, podemos ter vários aplicativos conectados com a mesma porta, cada um possuindo um Socket próprio. Os aplicativos em sua grande maioria abrem geralmente dois sockets, um Ativo e um Passivo. O ativo e usado para o envio de dados, o passivo e usado para o recebimento de dados. Geralmente, os Sockets são identificados pelo endereço IP da estação remota e o numero da porta utilizada.

 

Programas Cliente e Servidor

Baixar Arquivos

Organograma

Código Fonte (Cpp) Servidor

//---------------------------------------------------------------------------

 

#include <vcl.h>

#pragma hdrstop

 

#include "ServerMain.h"

 #include <vcl\registry.hpp>

 

//---------------------------------------------------------------------------

#pragma package(smart_init)

#pragma resource "*.dfm"

TForm1 *Form1;

//---------------------------------------------------------------------------

__fastcall TForm1::TForm1(TComponent* Owner)

  : TForm(Owner)

{

}

//---------------------------------------------------------------------------

 

void __fastcall TForm1::ServerClientRead(TObject *Sender,

      TCustomWinSocket *Socket)

{

  String MSG = Socket->ReceiveText();

  MSG = MSG.Trim();

  if(MSG.IsEmpty()) return;

 

  String Cod,Msg,FromIp,FromName;

  if(!Desmonta(MSG,Cod,FromIp,FromName,Msg)) return;

 

  if(Cod != 'D')

  {

    Adiciona(FromName,FromIp);

 

    if(Cod == 'M')

      EscreveLog(FromName+"-"+FromIp+": "+Msg,clBlue);

 

    if(Cod == 'C')

      EscreveLog(FromName+"-"+FromIp+", Conectou!",clBlack);

 

    if(Cod == 'S')

    {

      EscreveLog(FromName+"-"+FromIp+": "+Msg,clGreen);

      EscreveLog("Enviando dado para a porta serial...",clGreen);

      if(WriteSerial(Msg))

        EscreveLog("Dado enviado para a porta serial",clGreen);

      else

        EscreveLog("Dado não enviado para a porta serial",clRed);

    }

  }

  else

  {

    Remove(FromIp);

    EscreveLog(FromName+"-"+FromIp+", Desconectou!",clBlack);

  }

 

}

//---------------------------------------------------------------------------

bool TForm1::Desmonta(String MSG, String &Cod, String &FromIP, String &FromName, String&Msg)

{

  MSG = MSG.Trim();

  if(MSG.IsEmpty()) return false;

  if(MSG.AnsiPos(";")==0) return false;

 

 

  //Se for uma Mensagem//

  Cod = MSG[1];

  MSG = MSG.SubString(2,MSG.Length());

  //Separa o ip da frase//

  if(MSG.AnsiPos(";")!=0)

  {

    FromIP = MSG.SubString(1,MSG.AnsiPos(";")-1);

    MSG = MSG.SubString(MSG.AnsiPos(";")+1,MSG.Length());

  }

  //Separa o nome da frase//

  if(MSG.AnsiPos(";")!=0)

  {

    FromName = MSG.SubString(1,MSG.AnsiPos(";")-1);

    MSG = MSG.SubString(MSG.AnsiPos(";")+1,MSG.Length());

  }

  Msg = MSG;

  return true;

 

}

//---------------------------------------------------------------------------

void TForm1::Adiciona(String Nome, String IP)

{

  for(int i = 0; i < Nomes->Items->Count; i++)

  {

    String SIP = Nomes->Items->Item[i]->SubItems->Strings[0];

    if(SIP == IP){Nomes->Items->Item[i]->Caption = Nome;return;}

  }

 

  TListItem * Add = Nomes->Items->Add();

  Add->Caption = Nome;

  Add->SubItems->Add(IP);

 

}

//---------------------------------------------------------------------------

void TForm1::Remove(String IP)

{

 for(int i = 0; i < Nomes->Items->Count; i++)

  {

    String SIP = Nomes->Items->Item[i]->SubItems->Strings[0];

    if(SIP == IP){Nomes->Items->Delete(i--);}

  }

}

//---------------------------------------------------------------------------

void TForm1::EscreveLog(String Word, TColor Cor)

{

  Log->SelAttributes->Color = Cor;

  Log->Lines->Add(Word);

}

//---------------------------------------------------------------------------

 

void __fastcall TForm1::FormShow(TObject *Sender)

{

  TestSerial();

  LabIP->Caption = "IP = "+GetIP->LocalIP;

}

//---------------------------------------------------------------------------

bool TForm1::WriteSerial(String Word)

{

  HANDLE  hCom;

  char *NomePorta = ComboBoxPorta->Text.c_str();

 

  hCom = CreateFile(NomePorta,GENERIC_READ | GENERIC_WRITE,0,NULL,OPEN_EXISTING,0,NULL);

 

  SerialLab->Caption = "Ocupada!";

  SerialLab->Color = clRed;

 

  if(hCom == INVALID_HANDLE_VALUE)

  {

    EscreveLog("Erro ao tentar abrir a porta especificada.",clRed);

    return false;

  }

 

  DCB dcb;

 

  if( !GetCommState(hCom, &dcb))

  {

    EscreveLog("Erro ao tentar abrir a porta especificada...",clRed);

    return false;

  }

 

 

   AnsiString cmmd;

   cmmd = CBRate->Items->Strings[CBRate->ItemIndex];

   cmmd+= "," + CBParidade->Items->Strings[CBParidade->ItemIndex].SubString(0,1);

   cmmd+= "," + CBTamanho->Items->Strings[CBTamanho->ItemIndex];

   cmmd+= "," + CBStop->Items->Strings[CBStop->ItemIndex];

 

   BuildCommDCB(cmmd.c_str(), &dcb); //Atribui os valores a estrutura dcb.

 

 

  if( SetCommState(hCom, &dcb) == 0 )

  {

    EscreveLog("Erro ao tentar mudar o estado da porta serial especificada...",clRed);

    return false;

  }

 

  DWORD BytesEscritos = 0;

  int TamaString;

  char BufferEnvia[100];

  strcpy(BufferEnvia, Word.c_str());

  TamaString = strlen(BufferEnvia);

  WriteFile( hCom, BufferEnvia, TamaString, &BytesEscritos, NULL );

  SerialText->Text = BufferEnvia;

  CloseHandle( hCom );

 

  SerialLab->Caption = "Livre!";

  SerialLab->Color = clGreen;

 

  return true;

}

 

//---------------------------------------------------------------------------

 

void __fastcall TForm1::FormCreate(TObject *Sender)

{

  TRegistry *Registro = new TRegistry;

  TStringList *Lista = new TStringList;

 

  Registro->RootKey = HKEY_LOCAL_MACHINE;

  Registro->OpenKey("HARDWARE\\DEVICEMAP\\SERIALCOMM", false);

 

  Registro->GetValueNames(Lista);

 

  for(int indice=0; indice <= Lista->Count-1; indice++)

    Form1->ComboBoxPorta->Items->Add(Registro->ReadString( Lista->Strings[indice] ) );

 

  if( Form1->ComboBoxPorta->Items->Count > 0)

    Form1->ComboBoxPorta->ItemIndex = 0;

 

  Lista->Free();

  Registro->CloseKey();

  Registro->Free();

 

  if(ComboBoxPorta->Items->Count == 0)

    ShowMessage("Nenhuma porta serial encontrada!!!");

 

}

//---------------------------------------------------------------------------

 

void __fastcall TForm1::Button1Click(TObject *Sender)

{

  Button1->Enabled = false;

  Button2->Enabled = true;

  Server->Port = PSock->Text.ToInt();

  Server->Active = true;

  PSock->Enabled = false;

 

  ComboBoxPorta->Enabled = false;

  CBParidade->Enabled = false;

  CBStop->Enabled = false;

  CBTamanho->Enabled = false;

  CBRate->Enabled = false;

  FTPA->Enabled = false;

  User->Enabled = false;

  Password->Enabled = false;

 

  if(Server->Active)

  {

    EscreveLog("Servidor inicializado!",clGreen);

    EscreveLog("------------------------------------------------------------------",clGreen);

    EscreveLog("Porta(Socket) = "+PSock->Text,clGreen);

    EscreveLog("------------------------------------------------------------------",clGreen);

    EscreveLog("Porta Serial = "+ComboBoxPorta->Text,clGreen);

    EscreveLog("Paridade = "+CBParidade->Text,clGreen);

    EscreveLog("Stop Bits = "+CBStop->Text,clGreen);

    EscreveLog("Tamanho = "+CBTamanho->Text,clGreen);

    EscreveLog("BaudRate = "+CBRate->Text,clGreen);

    EscreveLog("------------------------------------------------------------------",clGreen);

    FTP->Host = FTPA->Text;

    FTP->UserID = User->Text;

    FTP->Password = Password->Text;

    FTP->Connect();

  }

  else

    EscreveLog("Falha ao inicializar o servidor!",clRed);

 

}

//---------------------------------------------------------------------------

 

void __fastcall TForm1::Button2Click(TObject *Sender)

{

  Button1->Enabled = true;

  Button2->Enabled = false;

  Server->Active = false;

  Nomes->Items->Clear();

  PSock->Enabled = true;

 

  ComboBoxPorta->Enabled = true;

  CBParidade->Enabled = true;

  CBStop->Enabled = true;

  CBTamanho->Enabled = true;

  CBRate->Enabled = true;

  FTPA->Enabled = true;

  User->Enabled = true;

  Password->Enabled = true;

 

  if(FTP->Connected)

  {

    FTP->Delete("SERVERIP.txt");

    FTP->Disconnect();

  }

 

  EscreveLog("Servidor terminado!",clGreen);

}

//---------------------------------------------------------------------------

 

 

void __fastcall TForm1::TrocarFonte1Click(TObject *Sender)

{

  Fonte->Font = Log->Font;

  if(Fonte->Execute())

    Log->Font = Fonte->Font;

}

//---------------------------------------------------------------------------

bool TForm1::TestSerial()

{

  HANDLE  hCom;

  char *NomePorta = ComboBoxPorta->Text.c_str();

  hCom = CreateFile(NomePorta,GENERIC_READ | GENERIC_WRITE,0,NULL,OPEN_EXISTING,0,NULL);

  if(hCom == INVALID_HANDLE_VALUE)

  {

    EscreveLog(ComboBoxPorta->Text+" em uso!!!",clRed);

    SerialLab->Caption = "Ocupada!";

    SerialLab->Color = clRed;

    return false;

  }

  SerialLab->Caption = "Livre!";

  SerialLab->Color = clGreen;

  CloseHandle( hCom );

  return true;

}

//---------------------------------------------------------------------------

void __fastcall TForm1::FTPConnect(TObject *Sender)

{

  String IP = GetIP->LocalIP;

  TStringList * File = new TStringList;

  File->Add(IP);

  File->Add(PSock->Text);

  File->SaveToFile("SERVERIP.txt");

  delete(File);

 

  FTP->Upload("SERVERIP.txt","SERVERIP.txt");

 

  EscreveLog("Conectado ao FTP!",clGreen);

  EscreveLog("Server = "+FTPA->Text,clGreen);

  EscreveLog("------------------------------------------------------------------",clGreen);

}

//---------------------------------------------------------------------------

 

void __fastcall TForm1::FTPConnectionFailed(TObject *Sender)

{

  EscreveLog("Falha ao conectar no FTP!",clRed);

}

//---------------------------------------------------------------------------

 

void __fastcall TForm1::FTPDisconnect(TObject *Sender)

{

  EscreveLog("Desconectado do FTP!",clGreen); 

}

//---------------------------------------------------------------------------

 

void __fastcall TForm1::FormClose(TObject *Sender, TCloseAction &Action)

{

if(Button2->Enabled)

  Button2Click(this);

}

//---------------------------------------------------------------------------

Código Fonte (Cpp) Cliente

//---------------------------------------------------------------------------

 

#include <vcl.h>

#pragma hdrstop

 

#include "ClientMain.h"

#include "GetIPu.h"

//---------------------------------------------------------------------------

#pragma package(smart_init)

#pragma resource "*.dfm"

TForm1 *Form1;

//---------------------------------------------------------------------------

__fastcall TForm1::TForm1(TComponent* Owner)

  : TForm(Owner)

{

}

//---------------------------------------------------------------------------

 

void __fastcall TForm1::FormShow(TObject *Sender)

{

  LabIP->Caption = "Ip local = "+GetIP->LocalIP; 

}

//---------------------------------------------------------------------------

 

void __fastcall TForm1::ClienteConnect(TObject *Sender,

      TCustomWinSocket *Socket)

{

  Conectar->Enabled = false;

  Desconectar->Enabled = true;

  Enviar->Enabled = true;

  Cliente->Socket->SendText("C"+GetIP->LocalIP+";"+Nome->Text+";");

  Porta->Enabled = false;

}

//---------------------------------------------------------------------------

 

void __fastcall TForm1::ClienteDisconnect(TObject *Sender,

      TCustomWinSocket *Socket)

{

  Cliente->Socket->SendText("D"+GetIP->LocalIP+";"+Nome->Text+";");

  Conectar->Enabled = true;

  Desconectar->Enabled = false;

  Enviar->Enabled = false;

  Porta->Enabled = true;

}

//---------------------------------------------------------------------------

void __fastcall TForm1::ConectarClick(TObject *Sender)

{

  Cliente->Address = Server->Text;

  Cliente->Active = true;

  Cliente->Port = Porta->Text.ToInt();

}

//---------------------------------------------------------------------------

void __fastcall TForm1::EnviarClick(TObject *Sender)

{

  if(Serial->Checked)

  Cliente->Socket->SendText("S"+GetIP->LocalIP+";"+Nome->Text+";"+Msg->Text);

  else

  Cliente->Socket->SendText("M"+GetIP->LocalIP+";"+Nome->Text+";"+Msg->Text);

}

//---------------------------------------------------------------------------

void __fastcall TForm1::DesconectarClick(TObject *Sender)

{

  Cliente->Active = false;

}

//---------------------------------------------------------------------------

 

void __fastcall TForm1::FormClose(TObject *Sender, TCloseAction &Action)

{

  if(Cliente->Active)

    Cliente->Active = false;

}

//---------------------------------------------------------------------------

 

void __fastcall TForm1::Button1Click(TObject *Sender)

{

  if(Form2->ShowModal() == mrOk)

  {

    FTP->Host = Form2->FTPA->Text;

    FTP->UserID = Form2->User->Text;

    FTP->Password = Form2->Password->Text;

 

    FTP->Connect();

  } 

}

//---------------------------------------------------------------------------

 

void __fastcall TForm1::FTPConnect(TObject *Sender)

{

  FTP->Download("SERVERIP.txt","SERVERIP.txt");

  if(FileExists("SERVERIP.txt"))

  {

    TStringList * File = new TStringList;

    File->LoadFromFile("SERVERIP.txt");

    Server->Text = File->Strings[0];

    Porta->Text = File->Strings[1];

    delete(File);

    DeleteFile("SERVERIP.txt");

  }

}

//---------------------------------------------------------------------------

 

void __fastcall TForm1::FTPError(TComponent *Sender, WORD Errno,

      AnsiString Errmsg)

{

  ShowMessage("Erro ao tentar acessar o FTP"); 

}

//---------------------------------------------------------------------------

 

void __fastcall TForm1::FTPUnSupportedFunction(TCmdType Trans_Type)

{

  ShowMessage("Erro ao tentar acessar o FTP");

}

//---------------------------------------------------------------------------