Programação em C/C++



Documentos relacionados
Engenharia Elétrica Eletrônica Slides 20: TCP/IP em Winsocks 2. API do Windows para programar utilizando o protocolo TCP/IP Prof. Jean Marcelo SIMÃO

Relatório do Laboratório 3

OO Engenharia Eletrônica

Laboratório - Exploração do FTP

Aula 30 - Sockets em Java

Na disciplina de Cálculo Numérico, vamos trabalhar com a linguagem C++ e o compilador que vamos usar é o Dev C++.

COMPARTILHAMENTO DO DISCO E PERMISSÕES DE REDE PÚBLICAS E DE GRUPOS DE TRABALHO.

Componentes da linguagem C++

Um Tutorial sobre Sockets Parte I

Conheça os principais comandos do Prompt do Windows; veja lista

Manual de Instalação de SQL Server (2005, 2008, 2012).

Algoritmos e Programação Estruturada

ECD1200 Equipamento de Consulta de Dados KIT DE DESENVOLVIMENTO

Sistemas de Operação Sockets

Programação de Sockets em C/C++

Programação com Sockets TCP e UDP - Cliente. Gustavo Leitão

06/10/2015. Modelo TCP/IP Camada de Transporte DISCIPLINA: TECNOLOGIA DE REDES DE COMPUTADORES. UDP User Datagram Protocol. UDP User Datagram Protocol

STK (Start Kit DARUMA) Utilizando conversor Serial/Ethernet com Mini-Impressora DR600/DR700.

ALTERNATIVA PARA CONEXÃO VIA INTERNET DE IP MASCARADO A IP REAL

Recuperando a comunicação com o seu Modem DSL-500G

Eclipse com c++11 e boost Etapa 1- Download da IDE Eclipse c++ e configuração do MinGW

INF1013 MODELAGEM DE SOFTWARE

Instalando e usando o Document Distributor 1

Abra o software de programação. Clique na opção VOIP, depois opção configuração conforme as imagens:

Manual de Instalação e Configuração do SQL Express

Orientação a Objetos Programação em C++

Print Audit 6 - Instalação do SQL Server 2008 express R2

INDICE 1. INTRODUÇÃO CONFIGURAÇÃO MÍNIMA INSTALAÇÃO INTERLIGAÇÃO DO SISTEMA ALGUNS RECURSOS SERVIDOR BAM...

O que é conexão de área de trabalho remoto?

Sistema de Instalação e Criação da Estrutura do Banco de Dados MANUAL DO INSTALADOR. Julho/2007. Ministério da saúde

Instruções de instalação e remoção para os drivers de impressora PostScript e PCL do Windows Versão 8

Aula pratica 4 Testar Conexões TCP/IP em Redes Industrias Usando os comandos Ping e Net View (1.a Parte)

Pilhas. Profa Morganna Diniz

Considerações a serem feitas antes da implantação.

Olho por olho, e o mundo acabará cego. Mohandas Gandhi

Instalando o Sysloc versão manualmente

Acesso Remoto Placas de captura

Orientação a Objetos. Programação em C++

Configurando um Grupo Doméstico e Compartilhando arquivos no Windows 7

Catálogo em Rede. Sumário

WinGate - Passo a passo

1 REQUISITOS BÁSICOS PARA INSTALAR O SMS PC REMOTO

1 Realizando testes de conexão

Guia e Utilização do Visual Studio 6.0

IP significa Internet Protocol. A Internet é uma rede, e assim como ocorre em qualquer tipo de rede, os seus nós (computadores, impressoras, etc.

Manual do Usuário. Tag List. Tag List Generator. smar FIRST IN FIELDBUS JUL / 02. Tag-List VERSÃO 1.0 TAGLSTC3MP

Uma aplicação distribuída

SUMÁRIO 1. AULA 6 ENDEREÇAMENTO IP:... 2

SAD Gestor Gerenciador de Backup

LIBERAÇÃO DA PASTA ARQUIVOS DE PROGRAMA

Passo a Passo da instalação da VPN

O que é uma rede de computadores?

ADMINISTRAÇÃO DE SISTEMAS OPERACIONAIS SERVIÇOS IMPRESSÃO. Professor Carlos Muniz

Resumo da Matéria de Linguagem de Programação. Linguagem C

Administração do Windows Server 2003

GUIA INTEGRA SERVICES E STATUS MONITOR

Compartilhamento de internet usando recursos do Windows XP

Manual de Instalação ProJuris8

É altamente recomendável testar as conexões usando o programa PING (será visto posteriormente).

Edwar Saliba Júnior. Dicas, Comandos e Exemplos Comparativos entre Linguagem Algorítmica e Linguagem C / C++

ITENS FUNDAMENTAIS. Profª Angélica da Silva Nunes

Roteador Load-Balance / Mikrotik RB750

Instalação e utilização do Document Distributor

COMO INSTALAR O CATÁLOGO

L A B O RATÓRIO DE REDES

Geral: Manual de Utilização do Software de Teste Gradual Windows

Aula Pratica 3 Configurações de Rede Ethernet com Protocolo TCP/IP

STK (Start Kit DARUMA) Procedimento de Instalação da FS700/MACH Conexão USB

Comunicação entre Processos

Como acessar o novo webmail da Educação? Manual do Usuário. 15/9/2009 Gerencia de Suporte, Redes e Novas Tecnologias Claudia M.S.

UNIVERSIDADE ESTADUAL DO OESTE DO PARANÁ CENTRO DE CIÊNCIAS EXATAS E TECNOLÓGICAS COLEGIADO DE INFORMÁTICA

TUTORIAL: MANTENDO O BANCO DE DADOS DE SEU SITE DENTRO DO DOMÍNIO DA USP USANDO O SSH!

3 SERVIÇOS IP. 3.1 Serviços IP e alguns aspectos de segurança

UNIVERSIDADE FEDERAL DO RIO GRANDE DO SUL INSTITUTO DE INFORMÁTICA INFORMÁTICA APLICADA

Configuração e Partilha de Pastas / ICS

MANUAL DE INSTALAÇÃO E PROGRAMAÇÃO CONVERSOR - IP / USB / SERIAL RV1

1. Introdução Instalação Baixando o arquivo Instalando Enviando SMS Configurando o Itcell sms massa...

GUIA MUDANÇA E FORMATAÇÃO DE SERVIDOR - SLIM

Eng.ª Informática. Redes de Computadores. Frequência. 4 de Julho de 2006

Manual de Instalação do Agente Citsmart

STK (Start Kit DARUMA) Procedimento de Instalação do Min200E Conexão USB

Docas do Pará - Guia de Instalação

INTRODUÇÃO AO JAVA PARA PROGRAMADORES C

Cartilha da Nota Fiscal Eletrônica 2.0 Hábil Empresarial PROFISSIONAL & Hábil Enterprise

Programando em C++ Histórico da Linguagem C

Portal do Senac: Área Exclusiva para Alunos Manual de Navegação e Operação

Procedimentos Operacionais Ambiente Microsoft Windows 2000 Server Máquina Smart02 ADM

Manual do Sistema "Fala Comigo - Sistema de Atendimento On-Line" Editorial Brazil Informatica

INFORMÁTICA APLICADA AULA 02 LINGUAGEM DE PROGRAMAÇÃO C++

Linguagem C Tipos de Dados. void; escalares; sizeof Vectores; strings em C Estruturas Introdução ao pré-processador

Configurando o DDNS Management System

Resolvendo problemas de conexão de rede wireless no pregão 83/2008

MDaemon GroupWare. Versão 1 Manual do Usuário. plugin para o Microsoft Outlook. Trabalhe em Equipe Usando o Outlook e o MDaemon

GUIA MUDANÇA E FORMATAÇÃO DE SERVIDOR - MILLENNIUM

Manual Instalação Pedido Eletrônico

Sistemas Distribuídos

FTP - Protocolo. O protocolo FTP é o serviço padrão da Internet para a transferência de arquivos entre computadores.

ROTEIRO PARA INSTALAÇÃO DO BITVISE, CONFIGURAÇÃO DE CHAVES SSH, DEFINIÇÃO DAS PORTAS PARA OS TÚNEIS SSH E CONFIGURAÇÃO DO THUNDERBIRD

15/8/2007 Gerencia de Tecnologia da Informação Claudia M.S. Tomaz

Transcrição:

OO Engenharia Eletrônica - Programação em C/C++ Slides 20: TCP/IP em Winsocks 2. API do Windows para programar aplicativos que utilizam o protocolo TCP/IP. Prof. Jean Marcelo SIMÃO

TCP/IP em Winsocks 2 Usando a API do Windows para programar aplicativos que utilizam o protocolo TCP/IP Obs.: Material inicial elaborado por André de Castilho Costa Pinto no 2o Semestre de 2007. O Castilho era então aluno da disciplina em questão e estagiário em projeto do Professor da disciplina.

Programa exemplo Explicações prévias: Toda comunicação depende de dois participantes: quem envia dados e quem recebe dados; O programa exemplo, portanto, é na verdade dois programas. Um servidor e um cliente. Neste caso o servidor é quem recebe certas informações e o cliente é quem envia tais informações. O cliente se conecta ao servidor para tal.

Programa exemplo

There s no place like 127.0.0.1 Vocês devem ter percebido que os dois programas estão rodando no mesmo computador... Acontece que, para não precisar montar uma rede toda vez que formos testar programas TCP/IP, podemos usar o endereço: 127.0.0.1. Este endereço de IP é chamado de localhost ou loopback, e referencia o próprio computador.

There s no place like 127.0.0.1 Uma prova prática disso é a seguinte: 1. Vá em Iniciar Executar cmd. 2. Desconecte o cabo da rede. 3. Digite ping localhost, ping 127.0.0.1 ou ainda ping loopback. 4. Veja que o PC,, mesmo sem estar conectado a nada, é capaz de pingar esse IP.

Antes de programar... Devemos conhecer: 1. Alguma ferramenta que monitora as portas; 2. Algum modo de descobrir o endereço de IP (Internet Protocol) ) de um computador.

Usando o bom e velho DOS O prompt de comando do Windows manteve vários comandos úteis do DOS, e, para monitorar o estado das portas do computador, utilizaremos o netstat. Este comando exibe uma lista das conexões estabelecidas no computador.

Usando o bom e velho DOS Para descobrir qual o ip de uma máquina, a maneira mais rápida é ir no prompt de comando e digitar ipconfig;

Antes de programar... Devemos saber o que é: 1. IP ( (Internet Protocol); 2. TCP ( (Transfer Control Protocol); 3. Socket; 4. Porta.

Internet Protocol Suite Protocolo de comunicação utilizado pela internet para estabelecer a conexão remota entre computadores. O protocolo de rede mais utilizado pela internet nos dias de hoje é o IPv4, mas poderá ser substituído pelo IPv6.

O protocolo IP

Protocolos de Transporte Os mais difundidos são o TCP e o UDP. TCP Transmission Control Protocol Ele é usado por outros protocolos de alto nível, como o FTP e o HTTP) UDP User Datagram Protocol

O protocolo TCP

Porta Número que associa os pacotes recebidos a um determinado processo rodando na máquina.

Socket É a união das duas informações necessárias à comunicação nos protocolos UDP e TCP. Um socket é formado por um endereço IP e uma porta.

E como se programa? Programa-se via API do Windows. A API (Application Programming Interface) ) do Windows constitui-se se em uma bibliotecas de funções que permite a qualquer um escrever códigos que rodem em Windows. A API inclui uma biblioteca que contém as funções que gerenciam e utilizam sockets para estabelecer conexões ou enviar pacotes de dados.

Primeiro Passo Já que vamos usar essa biblioteca, devemos dizer isso ao compilador. Deste modo, ele poderá reconhecer as funções que utilizaremos no programa. A biblioteca em questão é a ws2_32.lib lib, abreviação de winsocks2, para plataformas win32. Essas funções são implementadas em uma DLL (Dynamic Link Library) que já vem com o Windows. Dynamic Link Library ou Biblioteca de Ligação Dinâmica ( (DLL)) é uma biblioteca de ligação [ linkagem ] dinâmica contendo códigos ou dados, que podem ser compartilhados por diferentes programas aplicativos durante sua execução. http://www www.arnaut.eti.br/op/cppglos CPPGlos.htm,, visitado em 29/05/2008, às 9:22.

Enfim, como fazer As funções básicas são: 1. socket (...) 2. bind (...) 3. listen (...) 4. accept (...) 5. connect (...) 6. send (...) 7. recv (...) 8. WSAStartup (...) 9. closesocket (...)

O código

O código Versão 1

O código Versão 1 A parte do Servidor

Algumas classes já conhecidas que estão no projeto do servidor #ifndef _ALUNO_H_ #define _ALUNO_H_ #include "Pessoa.h" class Aluno : public Pessoa private: int int public: ; Aluno ( id; RA; Aluno ( int i ); Aluno ( ); ~Aluno ( ); void setra ( int ra ); int getra (); void setid (int I ); int getid ( ); #endif int diana, int mesna, int anona, char* nome = "", int i = 0, int r = 0 ); #ifndef _PROFESSOR_H_ #define _PROFESSOR_H_ #include "Pessoa.h" class Professor : public Pessoa private: float salario; float bolsa_projeto; public: Professor ( int diana, int mesna, int anona, char* nome = "", float sal = 0, float bp = 0); Professor ( ); ~Professor ( ); void setsalario ( float s ); float getsalario ( ); void setbolsaprojeto ( float bp ); float getbolsaprojeto ( ); void informaproventos ( ); ; #endif

Outras classes já conhecidas que estão no projeto do servidor #ifndef _PESSOA_H_ #define _PESSOA_H_ class Pessoa private:... public: #ifndef _LISTA_H_ #define _LISTA_H_ #include "Elemento.h" #include <iostream> using namespace std; template<class TIPO> class Lista private:... public:... ;... ;... #endif #ifndef _ELEMENTO_H_ #define _ELEMENTO_H_ template<class TIPO> class Elemento private:... public:... ;...

#ifndef _SERVIDOR_H_ #define _SERVIDOR_H_ Classe Servidor em servidor.h #include <winsock2.h> #include <windows.h> #include <process.h> #include "Lista.h" #include "Aluno.h" #include "Professor.h" class Servidor sockaddr_in meu_end; long int cont_msg; SOCKET meu_sock Sockt; bool tem_canal, tem_sockt, tem_conexao; int max_conexao, bytes_recebidos; // bytes recebidos, armazena o valor de retorno de recv char buffer [ 500 ]; Lista < Aluno > lalunos; Lista < Professor > lprofessor; public: Servidor ( char* ip = "127.0.0.1", unsigned short porta = 3077,, int max = 1); ~Servidor ( ); void conectasockt (); /*---------------------------------------------------------------- ---------------------------------------------------------------------- ------*/ void aceitasockt ( ) ; void lacodeconexao ( ); /*---------------------------------------------------------------- ---------------------------------------------------------------------- ------*/ void recebeclasse ( ); void cadastraaluno ( ); void cadastraprofessor ( ); ; #endif

#include "servidor.h" Classe Servidor construtora em servidor.cpp Servidor::Servidor ( char *ip, unsigned short porta, int max ) : cont_msg ( 0 ) WSADATA tst; if ( WSAStartup ( MAKEWORD ( 2, 2 ), &tst ) ) // teste para ver se o computador suporta e versão de winsocks utilizadau cout << " O computador nao possui a versao 2.0 do Winsocks. " ; else cout << " Nao sera possivel criar o servidor. " << endl; max_conexao = max; // Atribui os valores passados pelo construtor ao ip e ao endereço de porta meu_end.sin_family = AF_INET; meu_end.sin_addr.s_addr = inet_addr ( ip ); // AdressFamily-Internet será usado como padrão nesse programa. meu_end.sin_port = htons ( porta ); meu_sockt = socket ( AF_INET, SOCK_STREAM, IPPROTO_TCP ); // cria o socket; if ( meu_sockt == SOCKET_ERROR ) cout << " Erro na criacao do socket." << endl; tem_sockt = false; else tem_sockt = true;

Classe Servidor destrutora e conectasockt em servidor.cpp Servidor::~Servidor () closesocket ( meu_sockt ); void Servidor::conectaSockt () int result = -1; result = bind ( meu_sockt, reinterpret_cast < SOCKADDR* > ( &meu_end ), sizeof ( meu_end ) ) ; if ( result == -1 ) cout << Bind nao pode ser efetuado." << endl ; tem_canal = false ; else tem_canal = true ;

void Servidor::aceitaSockt () SOCKET outrosockt; // listen define o estado da porta aberta pelo servidor. // a porta fica esperando ("escutando") pedidos de conexões if ( listen ( meu_sockt, max_conexao ) == -1 ) cout << "Erro ao entrar em modo de espera de conexoes" << endl; tem_conexao = false; return; cout << "Aguardando conexoes..." << endl; // loop infinito... do Classe Servidor aceitasockt em servidor.cpp // função que aceita um pedido de conexão feito com "connect()" pelo cliente outrosockt = accept( meu_sockt, NULL, NULL ); while ( outrosockt == SOCKET_ERROR ); meu_sockt = outrosockt; cout << "Alguem conectou!" << endl; // envia uma mensagem confirmando a conexão para o cliente send ( meu_sockt, "Ola. Voce esta conectado ao servidor.", 38, 0 );

Classe Servidor lacodeconexao em servidor.cpp //função que define o loop que ficará esperando por mensagens do cliente void Servidor::lacoDeConexao() while (1) bytes_recebidos = recv ( meu_sockt, buffer, 500, 0 ); switch ( bytes_recebidos ) case -1: continue; case 2 : recebeclasse (); cout << "--------------------------------------------------------------------" << endl; break; case 0: cout << " Mensagem num. " << ++cont_msg << endl; cout << "\t Conexão fechada pelo cliente." << endl; shutdown ( meu_sockt, 1 ); closesocket( meu_sockt ); system ( "pause" ); WSACleanup (); exit ( EXIT_SUCCESS ); default: cout << "Mensagem num. " << ++cont_msg << endl; cout << "\t String de texto recebida."; cout << "\ta mensagem foi: \"; cout << buffer << "\"" << endl; strcpy ( buffer, "" );

void Servidor::recebeClasse () char *resp; resp = new char [ 2 ]; strcpy ( resp, "1" ); Classe Servidor recebeclasse em servidor.cpp send ( meu_sockt, resp, 2, 0 ); int tipo = atoi ( buffer ); do bytes_recebidos = recv ( meu_sockt, buffer, 500, 0 ); while ( bytes_recebidos == -1 ); switch ( tipo ) case 1: cadastraaluno(); break; case 2: cadastraprofessor(); break; default: cout << "Houve uma falha durante o recebimento, os dados podem estar corrompidos." << endl; break; lacodeconexao ();

void Servidor::cadastraAluno() Aluno *paux; paux = reinterpret_cast < Aluno * > ( buffer ); lalunos.setinfo ( paux, paux->getnome () ); cout << "Msg num." << ++cont_msg << endl; cout << " \taluno recebido e listado!" << endl; cout << " \to nome do aluno eh " << paux->getnome() << endl; void Servidor::cadastraProfessor () Classe Servidor cadastraaluno - cadastraprofessor Professor *paux; paux = reinterpret_cast < Professor *>( buffer); lprofessor.setinfo ( paux, paux->getnome() ); cout << "Msg num." << ++cont_msg << endl; cout << " \tprofessor recebido e listado!" << endl; cout << " \to nome do professor eh " << paux->getnome() << endl;

main () #include <iostream> #include <string> #include <stdlib.h> #include "servidor.h" using std::cout; using std::endl; main() Servidor serv; serv.conectasockt ( ); serv.aceitasockt (); serv.lacodeconexao (); system ( "pause" );

O código Versão 1 A parte do Cliente

Algumas classes já conhecidas que estão no projeto do cliente #ifndef _PESSOA_H_ #define _PESSOA_H_... class Pessoa private:... public:... ; #endif #ifndef _ALUNO_H_ #define _ALUNO_H_ #include "Pessoa.h" class Aluno : public Pessoa private:... public:... ; #endif #ifndef _PROFESSOR_H_ #define _PROFESSOR_H_ #include "Pessoa.h" class Professor : public Pessoa private:... public:... ; #endif

#ifndef _CLIENTE_H_ #define _CLIENTE_H_ #include <winsock2.h> #include <windows.h> #include "Aluno.h" #include "Pessoa.h" #include "Professor.h" class Cliente sockaddr_in serv_end; sockaddr_in meu_end; // OBS: na verdade, nao precisa ser definido o endereço do cliente SOCKET public: ; Cliente (); ~Cliente (); meu_sockt; void conectar ( char *ip, unsigned short porta ); void conectar ( ); void enviastring ( ); // Envia uma string de texto // A função que não recebe parâmetros pergunta ao usuario a porta a e o ip do server void criaenviaaluno ( char *nome, int RA, int ID ); // Envia um buffer contendo os dados referentes a um aluno; void criaenviaprofessor ( char *nome, float sal, float bp ); void rotinaprincipal ( ); // Rotina principal de envio de dados #endif A classe Cliente - em cliente.h

#include <iostream> using namespace std; #include "cliente.h" Cliente::Cliente ( ) WSADATA tst; if ( WSAStartup ( MAKEWORD ( 2, 2 ), &tst ) ) // teste para ver se o computador suporta e versão de winsocks utilizada izada // não deve dar problemas, já que todos os windows superiores ao 95 a suportam. cout << "O computador nao possui a versao 2.0 do Winsocks."; cout << " Nao sera possivel criar o servidor." << endl; return; meu_sockt = socket ( AF_INET, SOCK_STREAM, IPPROTO_TCP ); if ( meu_sockt == SOCKET_ERROR ) cout << "Nao foi possivel criar o socket." << endl; // define o endereço do cliente. // cria o socket. // existem funções que recuperam os ips reais de uma máquina nas respectivas redes das quais participa meu_end.sin_family A construtora da classe Cliente em cliente.cpp. = AF_INET; meu_end.sin_port = htons ( 50001 ); meu_end.sin_addr.s_addr = inet_addr ( "127.0.0.1" );

A destrutora da classe Cliente em cliente.cpp. Cliente::~Cliente ( ) closesocket ( meu_sockt );

O método conectar ( ) da classe Cliente em cliente.cpp. void Cliente::conectar ( ) char msg [ 38 ]; char ip [ 16 ]; cout << " Digite o ip do servidor ao qual quer se conectar. " << endl; cout << " \t obs: 127.0.0.1 para o local host \n"; fflush ( stdin ); gets ( ip ); conectar ( ip, 3077 );

void Cliente::conectar ( char* ip, unsigned short porta ) O método conectar (...) da classe Cliente em cliente.cpp. char msg [38] ; serv_end.sin_family = AF_INET; // define o endereço do servidor. serv_end.sin_addr.s_addr = inet_addr ( ip ); serv_end.sin_port = htons ( porta ); int result = 0; result = connect ( meu_sockt, reinterpret_cast < SOCKADDR * > ( &serv_end ), sizeof ( serv_end ) ); if ( result == -1 ) cout << " Nao foi possivel conectar ao servidor, tente de novo." << endl; return; cout << " Conexao estabelecida." << endl; while ( 1 ) result = recv ( meu_sockt, msg, 38, 0 ); if ( result!= -1 ) cout << msg << endl << endl; break; rotinaprincipal ( );

O método rotinaprincipal ( ) da classe Cliente em cliente.cpp. // rotina de envio, que contém o menu e a interface do usuario void Cliente::rotinaPrincipal ( ) char opc, nom [ 100 ]; int ra, id; float sal, bp; case '3': cout << "Digite o nome do prof. que deseja cadastrar." << endl; fflush ( stdin ); cout << "Digite sua opcao:" << endl; cout << "\t- 1 para enviar uma string;" << endl; cout << "\t- 2 para enviar um aluno;" << endl; cout << "\t- 3 para enviar um professor;" << endl; cout << "\t- x para sair." << endl; cin >> opc; switch ( opc ) case '1': enviastring (); system ( "cls" ); rotinaprincipal (); break; case '2': cout << "Digite o nome do aluno que deseja cadastrar." << endl; flush ( stdin ); gets ( nom ); cout << "Digite o RA." << endl; cin >> ra; cout << "Digite a ID." << endl; cin >> id; criaenviaaluno ( nom, ra, id ); system ( "cls" ); rotinaprincipal ( ); break; gets ( nom ); cout << " Digite o salario." << endl; cin >> sal; cout << "Digite o valor da bolsa projeto." << endl; cin >> bp; criaenviaprofessor ( nom, sal, bp ); system ( "cls" ); rotinaprincipal (); break; case 'x': case 'X': shutdown ( meu_sockt, 1 ); closesocket ( meu_sockt ); system ("Pause"); exit ( EXIT_SUCCESS ); break; default: cout << "Opcao invalida." << endl; system ( "cls" ); rotinaprincipal ( ); break;

O método enviastring( ) da classe Cliente em cliente.cpp. void Cliente::enviaString ( ) char msg [ 500 ]; cout << " Digite a msg que deseja enviar: " << endl; fflush ( stdin ); gets ( msg ); send ( meu_sockt, msg, strlen ( msg ) + 1, 0 );

O método cadastraaluno (...) da classe Cliente em cliente.cpp. void Cliente::criaEnviaAluno ( char* nome, int RA, int ID ) Aluno *aux; // é criado o objeto da classe aluno que será enviado; char *buff; // um buffer que conterá os dados do aluno; int tipo; char *inf; inf = new char [ 2 ]; strcpy ( inf, "1"); // Rotina que diz ao servidor qual o tipo de dado que está sendo enviado send ( meu_sockt, inf, 2, 0 ); while ( recv ( meu_sockt, inf, 2, 0 ) == -1 ); tipo = atoi ( inf ); // inf recebe 1 para sinalizar que é um aluno, e 2 que é um professor or // fica em loop até receber resposta do servidor if ( tipo == 1 ) aux = new Aluno ( 0, 0, 0, nome, RA, ID ); // o buffer é inicializado com o tamanho (em bytes) da estrutura aluno // como 1 char tem 1 byte, todo o vetor "buff" terá o mesmo tamanho em bytes que um objeto aluno; buff = new char [ sizeof ( Aluno ) ]; // dizemos ao compilador que, em vez dele entender aux como um aluno, ele deve interpretá-lo como um vetor de char. // Ou u seja, estamos interpretando aux não como um objeto aluno, mas como um vetor de bytes. buff = reinterpret_cast < char * > ( aux ); // agora podemos enviar os bytes, que, juntos, representam um aluno,, para o servidor. send ( meu_sockt, buff, sizeof ( Aluno ), 0 ); system ( "pause" ); else cout << "Nao foi possivel enviar o aluno." << endl;

O método cadastraprofessor (...) da classe Cliente em cliente.cpp. void Cliente:: ::criaenviaprofessor ( char *nome* nome, float sal, float bp ) Professor *aux* aux; char *buff; char *inf; int tipo; inf = new char [ 2 ]; strcpy ( inf, "2" ); send ( meu_sockt, inf, 2, 0 ); while ( recv ( meu_sockt, inf, 2, 0 ) == -1 ); tipo = atoi ( inf ); if ( tipo == 1 ) aux = new Professor ( 0, 0, 0, nome, sal, bp ); buff = new char[ sizeof ( Professor ) ]; buff = reinterpret_cast < char * > ( aux ); send ( meu_sockt, buff, sizeof ( Professor ), 0 ); delete aux; else cout << "Nao" foi possivel enviar o professor." " << endl;

A função main() em main.cpp. #include "cliente.h" #include <iostream> #include <stdlib< stdlib.h> using std::cout; using std::endl endl; int main ( ) Cliente cl; cl.conectar conectar (); system ( "pause" ) ; return 0;

O código Versão 2 usando Threads.

O código Versão 2 A parte do Servidor A parte do servidor mudou ligeiramente no servidor.h e.cpp e mudou na main.cpp.

Mudanças no servidor.h e.cpp.... class Servidor CRITICAL_SECTION *cs; int *iter;...... void Servidor::listaAlunos ( ) lalunos.listeinfos ( ); public: Servidor (... ); CRITICAL_SECTION *pcs, int *it, char *ip = "127.0.0.1", unsigned short porta = 3077, int max = 1 void Servidor::listaProfessores ( ) lprofessor.listeinfos ( ); void listaalunos ( ) ; void listaprofessores ( ) ; ;...

Servidor::Servidor ( CRITICAL_SECTION *pcs,, int *it* it, char *ip, unsigned short porta, int max ): cont_msg ( 0 ) WSADATA tst; cs = pcs; iter = it; if ( WSAStartup ( MAKEWORD ( 2, 2 ), &tst ) ) // teste para ver se o computador suporta e versão de winsocks utilizada cout << " O computador nao possui a versao 2.0 do Winsocks. "; cout << " Nao sera possivel criar o servidor. " << endl; else max_conexao = max; // Atribui os valores passados pelo construtor ao ip e ao endereço de porta // AdressFamily-Internet será usado como padrão nesse programa meu_end.sin_family = AF_INET; meu_end.sin_addr.s_addr = inet_addr ( ip ); meu_end.sin_port = htons ( porta ); // cria o socket; meu_sockt = socket ( AF_INET, SOCK_STREAM, IPPROTO_TCP ); if ( meu_sockt == SOCKET_ERROR ) cout << " Erro na criacao do socket." << endl; tem_sockt = false; else tem_sockt = true;

void Servidor::aceitaSockt ( ) SOCKET outrosockt; // listen define o estado da porta aberta pelo servidor. // a porta fica esperando ("escutando") pedidos de conexões if ( listen ( meu_sockt, max_conexao ) == -1 ) cout << "Erro ao entrar em modo de espera de conexoes" << endl; tem_conexao = false; return; EnterCriticalSection ( cs ); cout << "Aguardando conexoes...\n" << endl; LeaveCriticalSection ( cs ); Sleep ( 10 ); // loop infinito... dá para implementar, por meio de comandos que façam o thread parar // de ser executado e uma variável de controle, um método que gerencie um possível "time out do // função que aceita um pedido de conexão feito com "connect()" pelo cliente outrosockt = accept ( meu_sockt, NULL, NULL ); while ( outrosockt == SOCKET_ERROR ); meu_sockt = outrosockt; EnterCriticalSection ( cs ); cout << " Alguem conectou! " << endl; LeaveCriticalSection ( cs ); Sleep ( 10 ); // envia uma mensagem confirmando a conexão para o cliente send ( meu_sockt, Ola. Voce esta conectado ao servidor. ", 38, 0 );

// função que define o loop que ficará esperando por mensagens do cliente void Servidor::lacoDeConexao ( ) while ( *iter ) bytes_recebidos = recv ( meu_sockt, buffer, 500, 0 ); if ( bytes_recebidos!= -1 ) EnterCriticalSection ( cs ); switch ( bytes_recebidos ) case 2: recebeclasse ( ); cout << "-----------------------------------------------------------------" << endl; break; case 0: cout << " Mensagem num. " << ++cont_msg << endl; cout << "\t Conexão fechada pelo cliente." << endl; shutdown ( meu_sockt, 1 ); closesocket ( meu_sockt ); system ( "pause" ); WSACleanup ( ); exit ( EXIT_SUCCESS ); break; default: cout << "Mensagem num. " << ++cont_msg << endl; cout << "\t String de texto recebida."; cout << " \ta mensagem foi: \ "; cout << buffer << "\"" << endl; LeaveCriticalSection ( cs ); Sleep ( 10 ); strcpy ( buffer, "" ); cout << " Conexao fechada." << endl;

Mudanças no main.cpp #include <windows.h> CRITICAL_SECTION cs; int iter = 1; // flag que sinaliza o processo de loopconexao // caso o usuario queira sair do programa #include "servidor.h" void interfaceusuario ( void *param ) ; main ( ) Servidor serv ( &cs, &iter ); InitializeCriticalSection ( &cs ); serv.conectasockt ( ); _beginthread ( interfaceusuario, 0, &serv ); serv.aceitasockt ( ); serv.lacodeconexao ( ); WSACleanup ( ); // fecha portas, socks... system ( "pause" ); void interfaceusuario ( void *param ) int opc; Servidor *serv1; serv1 = reinterpret_cast < Servidor *> ( param ); while ( iter ) EnterCriticalSection ( &cs ); cout << " Servidor versao 0.2: " << endl; cout << " \t Qual sua opcao? " << endl; cout << " \t 1 - Listar Alunos" << endl; cout << " \t 2 - Listar Professores"; << endl; cout << " \n\t 3 - Sair" << endl; LeaveCriticalSection ( &cs ); cin >> opc; switch ( opc ) case 1: EnterCriticalSection ( &cs ); serv1->listaalunos ( ); cout << endl; system ( "pause" ); LeaveCriticalSection ( &cs ); break; case 2: EnterCriticalSection ( &cs ); serv1->listaprofessores (); cout << endl; system ( "pause" ); LeaveCriticalSection ( &cs ); break; case 3: WSACleanup (); exit ( EXIT_SUCCESS ); break; default: system ("cls"); continue; system ( "cls" ); Sleep ( 10 );

O código Versão 2 A Parte do Cliente A parte do cliente não mudou. Essencialmente, é o mesmo código

Problemas com o Dev Quando for criado um projeto com o Dev++, pode ocorrer erro de ligação ( linkedição ) em algumas versões desse. Cf. o erro, uma solução poder ser o seguinte procedimento : Vá na opção de menu Projeto e depois na sub-opção de menu Opções do Projeto. Selecione a aba Parâmetros e em Linker Linker clique no botão Adicionar Encontre o diretório (pasta) onde foi instalado o DevCpp (talvez na raiz, talvez em arquivos de programa ). Encontre o subdiretório Lib Lib. Encontre e selecione o arquivo libws2_32a. Clique no botão Abrir. Clique no botão OK. Vá na opção de menu Executar e depois na sub-opção de menu Recompilar tudo.