Pontifícia Universidade Católica do Rio Grande do Sul
– Pucrs
Aluno: Roberto Bender – rbender@ee.pucrs.br
Apresentação de Programação de Periféricos
Acesso a periférico remoto via internet
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
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");
}
//---------------------------------------------------------------------------