Como conectar-se a um soquete de fluxo
Idioma: HTML | XAML

Como se conectar com um soquete de fluxo (XAML)

[ Este artigo destina-se aos desenvolvedores do Windows 8.x e do Windows Phone 8.x que escrevem aplicativos do Windows Runtime. Se você estiver desenvolvendo para o Windows 10, consulte documentação mais recente]

Este tópico mostra como habilitar um aplicativo do Tempo de Execução do Windows para enviar e receber dados com um soquete de fluxo TCP usando um StreamSocket. O soquete TCP permite transferências de dados de rede de baixo nível em qualquer direção para conexões de longa duração. Soquetes TCP são o recurso subjacente usado pela maioria dos protocolos de rede disponíveis na Internet.

O exemplo cria um soquete TCP para estabelecer uma conexão de rede, usa esse soquete para enviar e receber dados e depois fecha o soquete.

O exemplo demonstra os seguintes recursos:

  • Usar a classe StreamSocket para criar um soquete TCP.
  • Criar uma conexão de rede com um servidor de rede TCP usando um dos métodos StreamSocket.ConnectAsync.
  • Enviar dados ao servidor usando o objeto Streams.DataWriter, que permite ao programador escrever tipos comuns (inteiros e cadeias de caracteres, por exemplo) em um fluxo.
  • Receber dados do servidor usando o objeto Streams.DataReader, que permite ao programador ler tipos comuns (inteiros e cadeias de caracteres, por exemplo) em um fluxo.
  • Feche o StreamSocket.

Pré-requisitos

Os seguintes exemplos usam C# e C++ e são vagamente baseados no Exemplo de StreamSocket. Para obter instruções sobre a criação de um aplicativo do Tempo de Execução do Windows em C# ou Visual Basic, consulte Criar seu primeiro aplicativo do Tempo de Execução do Windows em C# ou Visual Basic. Para obter instruções sobre a criação de um aplicativo do Tempo de Execução do Windows usando C++, veja Criar o primeiro aplicativo de Tempo de Execução do Windows usando C++.

Para garantir que o aplicativo do Tempo de Execução do Windows esteja pronto para a rede, defina alguns recursos de rede no arquivo Package.appxmanifest do projeto. Para obter mais informações, consulte Como definir recursos de rede.

Criar um novo projeto

  1. Abra o Microsoft Visual Studio 2013 e selecione Novo Projeto no menu Arquivo.
  2. Na lista de modelos, escolha Visual C# ou Visual C++ (dependendo da sua linguagem de desenvolvimento preferida).
  3. Na seção, escolha Store apps.
  4. Na seção, selecione Universal Apps, Windows apps ou Windows Phone apps (dependendo da plataforma que você deseja) e selecione Aplicativo em Branco.
  5. Nomeie o aplicativo StreamSocketBasic e clique em OK.

Definir recursos para permitir acesso à rede

Você precisa definir as capacidades de rede para o seu aplicativo para permitir o acesso à rede local e à Internet. Para que um aplicativo que usa StreamSocket se conecte a um serviço de rede em um computador diferente, ele precisa de capacidades de rede definidas. Se o aplicativo precisa ser capaz de conectar-se como um cliente aos serviços remotos na Internet, a capacidade de Internet (Cliente) é necessária. Se for necessário que o aplicativo possa se conectar como um cliente a serviços remotos em uma rede doméstica ou corporativa, o recurso Redes Privadas (Cliente e Servidor) será necessário.

Observação  No Windows Phone, há apenas um recurso de rede, Internet (Cliente e Servidor), que permite o total acesso à rede do aplicativo.
 

Para obter mais informações sobre acesso à rede, consulte Como configurar as capacidades de isolamento de rede.

As etapas a seguir mostram como definir capacidades de rede.

  1. Use o Microsoft Visual Studio para abrir o arquivo package.appxmanifest.
  2. Selecione a guia Recursos.
  3. Para criar a versão de exemplo do Windows, selecione os recursos Internet (Cliente) e Redes Privadas (Cliente e Servidor).

    Para criar a versão de exemplo do Windows Phone, selecione o recurso Internet (Cliente e Servidor).

  4. Salve e feche o arquivo de manifesto.

Adicionar a interface do usuário XAML

  • Nesta seção, definiremos o layout do aplicativo em XAML para especificar o tamanho e a posição de cada objeto no aplicativo. Complete a interface do usuário do aplicativo adicionando controles e conteúdo para exibir dados.

    Esta amostra usa elementos simples de interface do usuário XAML que incluem:

    • Um StackPanel horizontal que contém um TextBlock para um rótulo, um TextBox para inserir o nome de host ou endereço IP do servidor, um TextBox para inserir o nome do serviço ou número da porta TCP para conexão e um Button usado para iniciar a solicitação assíncrona.
    • Um StackPanel horizontal que contém um TextBlock para um rótulo, um TextBox para dados de texto de entrada a serem enviados ao servidor e um Button usado para iniciar a solicitação assíncrona de envio dos dados.
    • Um StackPanel horizontal que contém um TextBlock como rótulo e uma TextBox para o status atual. É aí que o status e as mensagens de erro são exibidos.
    • Uma Grid na qual qualquer saída recebida do serviço de rede é exibida. Neste exemplo, todos os dados de texto recebidos são exibidos como texto sem formatação.

    Para ver um exemplo de Visual C#, abra a pasta cs. Para ver um exemplo de Visual C++, abra a pasta cpp. Abra o arquivo blankPage.xaml existente e renomeie o arquivo como MainPage.xaml. Adicione os seguintes elementos de interface do usuário a esse arquivo.

    Observação  O código XAML abaixo precisará ser alterado para um aplicativo da Loja do Windows Phone.
     
    
    <Page
        x:Class="StreamSocketBasic.BlankPage"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:local="using:StreamSocketBasic"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        mc:Ignorable="d">
    
        <Grid Background="{StaticResource ApplicationPageBackgroundBrush}">
            <StackPanel Orientation="Vertical">
                <StackPanel Orientation="Horizontal">
                    <TextBlock Text="Hostname:" FontSize="16" Height="20"  Margin="15,0,0,0" />
                    <TextBox x:Name="ServerHostname" Text="www.contoso.com" FontSize="16" Height="20" Margin="15,0,0,0" />
                    <TextBlock Text="Port:" FontSize="16" Height="20"  Margin="15,0,0,0" />
                    <TextBox x:Name="ServerPort" Text="http" FontSize="16" Height="20" Margin="15,0,0,0" />
                    <Button Content="Connect" Click="Connect_Click" Margin="220,0,0,0" />
                </StackPanel>
                <StackPanel Orientation="Horizontal">
                    <TextBlock Text="Text to send:" FontSize="16" Height="20"  Margin="15,0,0,0" />
                    <TextBox x:Name="SendText" Text="hello" FontSize="16" Height="20" Margin="15,0,0,0" />
                    <Button Content="Send" Click="Send_Click" Margin="220,0,0,0" />
                </StackPanel>
                <StackPanel Orientation="Horizontal">
                    <TextBlock Text="Status:" FontSize="16" Height="20" Margin="15,0,0,0" />
                    <TextBox x:Name="StatusText" Text="Idle" FontSize="16" Height="Auto" TextWrapping="Wrap" Margin="15,0,0,0" />
                </StackPanel>
                <Grid 
                    Grid.Column="1" Margin="15,0,0,0">
                    <Grid.RowDefinitions>
                        <RowDefinition Height="Auto" />
                    </Grid.RowDefinitions>
                    <TextBlock x:Name="OutputView" FontSize="16" Height="Auto" Margin="15,0,0,0" TextWrapping="Wrap" />
                </Grid>    
            </StackPanel>
         </Grid>
    </Page>
    
    
    

Criar o StreamSocket e conectar-se ao servidor.

O código nessa etapa cria algumas variáveis, entre elas o soquete de cliente e variáveis que acompanham o status. As variáveis são criadas para acompanhar se o soquete de cliente está em um estado conectado ou de fechamento. Esta etapa também define o nome de host e nome do serviço (porta TCP) à qual conectar no servidor. O valor do nome de host e nome do serviço são definidos com um valor padrão que pode ser alterado na interface do usuário.

  1. Crie primeiro o objeto StreamSocket.

    Abra a pasta cs. Abra o arquivo MainPage.cs e adicione o seguinte código a ele.

    
    
    using Windows.Networking;
    using Windows.Networking.Sockets;
    
    
        private StreamSocket clientSocket;
        private HostName serverHost;
        private string serverHostnameString;
        private string serverPort;
        private bool connected = false;
        private bool closing = false;
    
        public BlankPage()
        {
            this.InitializeComponent();
            clientSocket = new StreamSocket();
        }
    
    
    
  2. Tente se conectar ao servidor.

    A maioria do trabalho é feita no manipulador de cliques do Connect.Button. Quando você clica nesse botão, o texto nos elementos de interface do usuário StatusText e OutputView é atualizado. O nome de host do servidor e o nome do serviço (porta) são usados para tentar e estabelecer uma conexão com o servidor e esperar a resposta. Se ocorrer um erro ou uma exceção, o resultado será exibido no elemento de interface do usuário StatusText. Se uma conexão for estabelecida e não houver erros, o StatusText será atualizado.

    Dados recebidos do servidor de rede são exibidos no elemento de interface do usuário OutputView.

    Quando você usa a palavra-chave await no C# e no Visual Basic, também deve definir o método como assíncrono. Usando a palavra-chave await no C# e no Visual Basic, o código para criar a conexão de maneira assíncrona é semelhante ao código que usaríamos para concluir essa operação de maneira síncrona.

    O método ConnectAsync(HostName, String) emitirá uma exceção se uma conexão TCP não puder ser estabelecida com o servidor de rede. O exemplo de código usa um bloco try/catch para capturar uma exceção e imprime a mensagem de exceção no elemento de interface do usuário StatusText, caso ocorra um erro. No bloco try, atualize o status.

    
            private async void Connect_Click(object sender, RoutedEventArgs e)
            {
                if (connected) {
                   StatusText.Text = "Already connected";
                   return;
                }
    
                try
                {
                    OutputView.Text = "";
                    StatusText.Text = "Trying to connect ...";
    
                    serverHost = new HostName(serverHostname.Text);
                    // Try to connect to the 
                    await clientSocket.ConnectAsync(serverHost, serverPort.Text);
                    connected = true;
                    StatusText.Text = "Connection established"+Environment.NewLine;
    
                }
                catch (Exception exception) {
                    // If this is an unknown status, 
                    // it means that the error is fatal and retry will likely fail.
                    if (SocketError.GetStatus(exception.HResult) == SocketErrorStatus.Unknown) {
                        throw;
                     }
    
                    StatusText.Text = "Connect failed with error: " + exception.Message;
                    // Could retry the connection, but for this simple example
                    // just close the socket.
    
                    closing = true;
                    // the Close method is mapped to the C# Dispose
                    clientSocket.Dispose();
                    clientSocket = null;
                      
                }
            }
    
    
    
    

Enviar dados e receber respostas do servidor

O código nesta etapa envia dados ao servidor e recebe respostas do servidor.

  • A maioria do trabalho é feita no manipulador de cliques do Button Enviar. Quando esse botão é clicado, o texto nos elementos da interface do usuário StatusText e OutputView é atualizado e, em seguida, o aplicativo tenta enviar ao servidor os dados de texto inseridos no elemento de interface do usuário Sendtext e tenta receber uma resposta. Se ocorrer um erro ou uma exceção, o resultado será exibido no elemento de interface do usuário StatusText. Se os dados forem enviados e não ocorrerem erros, StatusText será atualizado.

    Dados recebidos do servidor de rede são exibidos no elemento de interface do usuário OutputView.

    Usando a palavra-chave await no C# e no Visual Basic, o código para enviar os dados e recuperar a resposta de maneira assíncrona é semelhante ao código que usaríamos para concluir essa operação de maneira síncrona. Você pode usar a palavra-chave await apenas quando o método é definido como async.

    O método DataWriter.StoreAsync lançará uma exceção se os dados não puderem ser enviados via conexão TCP ao servidor de rede. Use um bloco try/catch para quaisquer exceções e para gerar a mensagem de exceção no elemento de interface do usuário StatusText se ocorrer um erro. No bloco try, atualize o status.

    
            private async void Send_Click(object sender, RoutedEventArgs e)
            {
                if (!connected) {
                   StatusText.Text = "Must be connected to send!";
                   return;
                }
    
                Int32 len = 0; // Gets the UTF-8 string length.
    
                try
                {
                    OutputView.Text = "";
                    StatusText.Text = "Trying to send data ...";
    
                    // add a newline to the text to send
                    string sendData = SendText.Text + Environment.NewLine; 
                    DataWriter writer = new DataWriter(clientSocket.OutputStream);
                    Int32 len = writer.MeasureString(sendData); // Gets the UTF-8 string length.
    
                    // Call StoreAsync method to store the data to a backing stream
                    await writer.StoreAsync();
    
                    StatusText.Text = "Data was sent"+Environment.NewLine;
    
                    // detach the stream and close it
                    writer.DetachStream();
                    writer.Dispose();
    
                 }
                catch (Exception exception) {
                    // If this is an unknown status, 
                    // it means that the error is fatal and retry will likely fail.
                    if (SocketError.GetStatus(exception.HResult) == SocketErrorStatus.Unknown) {
                        throw;
                     }
    
                    StatusText.Text = "Send data or receive failed with error: " + exception.Message;
                    // Could retry the connection, but for this simple example
                    // just close the socket.
    
                    closing = true;
                    clientSocket.Dispose();
                    clientSocket = null;
                    connected = false;
                      
                }
    
                // Now try to receive data from server
                try
                {
                    OutputView.Text = "";
                    StatusText.Text = "Trying to receive data ...";
    
                    DataReader reader = new DataReader(clientSocket.InputStream);
                    // Set inputstream options so that we don't have to know the data size
                    reader.InputStreamOptions = Partial;
                    await reader.LoadAsync(reader.UnconsumedBufferLength);  
    
                 }
                catch (Exception exception) {
                    // If this is an unknown status, 
                    // it means that the error is fatal and retry will likely fail.
                    if (SocketError.GetStatus(exception.HResult) == SocketErrorStatus.Unknown) {
                        throw;
                     }
    
                    StatusText.Text = "Receive failed with error: " + exception.Message;
                    // Could retry, but for this simple example
                    // just close the socket.
    
                    closing = true;
                    clientSocket.Dispose();
                    clientSocket = null;
                    connected = false;
                      
                }
            }
    
    
    
    

Execute o aplicativo

  • Para executar o aplicativo, pressione F5 no Microsoft Visual Studio Express 2012 para o Windows 8 executar o projeto. Selecione os botões para estabelecer uma conexão, enviar dados e fechar o soquete.

Resumo e próximas etapas

Neste tópico, você criou um aplicativo que usa um soquete de fluxo TCP para estabelecer uma conexão de rede e enviar dados usando um objeto StreamSocket.

Também é possível usar um soquete de datagrama para estabelecer uma conexão de rede para enviar dados. Para obter um exemplo, consulte Como se conectar com um soquete de datagrama.

Tópicos relacionados

Outros recursos
Conectando-se com soquetes
Como configurar recursos de rede
Como se conectar com um soquete de datagrama
Como proteger conexões de soquete com TLS/SSL
Como definir tempos limite em operações de soquete
Como usar controle avançados de soquetes
Solucione problemas e depure conexões de rede
Referência
Windows.Networking
Windows.Networking.Connectivity
Windows.Networking.Sockets
Exemplos
Exemplo de StreamSocket

 

 

Mostrar:
© 2017 Microsoft