Windows 10 开发 网络编程教程

本教程的主要内容:HttpClient类,Socket通信,WCF通信

 HttpClient类

 在UWP中可以用来进行网络通信的HttpClient类有两个,System.Net.Http.HttpClient和Windows.Web.Http.HttpClient,两者使用上的差别并不大,但我们优先考虑后者,因为它位于Windows.Foundation.UniversalApiContract程序集中,是本地代码,效率更高。我们主要学习的也是Windows.Web.Http.HttpClient了。

 使用HttpClient类,我们可以向指定的URI发出HTTP请求,并获取从服务器返回的数据。发起请求的方式有GET、POST、 PUT和 DELETE,请求都是异步请求。同时我们还需要一个HttpResponseMessage对象,用来声明从 HTTP 请求接收到的 HTTP 响应消息。

  HttpClient httpClient = new HttpClient();

 //添加用户代理标头

  httpClient.DefaultRequestHeaders.Add("user-agent", "Mozilla/5.0 (compatible;MSIE 10.0;Windows NT 6.2;WOW64;Trident/6.0)");

  HttpResponseMessage response =  await httpClient.GetAsync(new Uri(tbUrl.Text));//发送请求,此处是GET的方式,其他方式类似

  response.EnsureSuccessStatusCode();//确保请求成功

 //Buffer方式读取返回结果

  IBuffer buffer = await response.Content.ReadAsBufferAsync();

  //流方式读取返回结果

   IInputStream inputStream= await response.Content.ReadAsInputStreamAsync();

  //字符串方式读取返回结果

  string result = await response.Content.ReadAsStringAsync();

  上面是HttpClient类来实现HTTP请求的一般方式了,ok,看常规演示:

  请求HTML页面:我们请求返回的HTML,最后都转换成了string类型,然后将这个string类型的值给了WebView控件的NavigateToString方法,它会自动处理HTML标记。(PS:你如果觉得这样还不如直接把URI给WebView控件的Navigate方法,反正显示效果一样,那你就把string值用其他文本控件显示吧!)还有,读取字符串直接用ReadAsStringAsync方法就行啦,后面的只为折腾一下。

  private async void btn_get_Click(object sender, RoutedEventArgs e)
    {
        //http://static.cnblogs.com/images/logo_small.gif
        //http://www.cnblogs.com/czhwust/p/Win10_file.html
        HttpClient httpClient = new HttpClient();
        httpClient.DefaultRequestHeaders.Add("user-agent", "Mozilla/5.0 (compatible;MSIE 10.0;Windows NT 6.2;WOW64;Trident/6.0)");
        if (String.IsNullOrEmpty(tbUrl.Text))
        {
            tbstatus.Text = "输入的URL为空";
        }
        else
        {
            try
            {                
                tbstatus.Text = " 等待响应......";
                HttpResponseMessage response =  await httpClient.GetAsync(new Uri(tbUrl.Text));
           
                response.EnsureSuccessStatusCode();//确保请求成功
                tbstatus.Text = response.StatusCode + " " + response.ReasonPhrase;
                //请求html
                //字符串方式读取返回结果
                string result = await response.Content.ReadAsStringAsync();
                wv.NavigateToString(result);
                //Buffer方式读取
                //IBuffer buffer = await   response.Content.ReadAsBufferAsync();
                //using (var dataReader = DataReader.FromBuffer(buffer))
                //{
                //    string result = dataReader.ReadString(buffer.Length);
                //    wv.NavigateToString(result);
                //}
                //Stream方式读取
                //var inputstream = await  response.Content.ReadAsInputStreamAsync();
                // Stream stream= inputstream.AsStreamForRead();
                // using (StreamReader reader=new StreamReader(stream))
                // {
                //   string result= reader.ReadToEnd();
                //   wv.NavigateToString(result);
                // }               
            }
            catch (Exception ex)
            {
                tbstatus.Text = ex.ToString();
            }
        }
    }

 请求图片:在请求图片的时候,WriteToStreamAsync方法最简捷,后面的同样是为了折腾,但可以仔细体会一下。。。(PS:直接把网络图片的地址赋值给Image控件的Source属性就能显示图片啦,我是砸场子的!)

private async void btn_get_Click(object sender, RoutedEventArgs e)
    {
        //http://static.cnblogs.com/images/logo_small.gif
        //http://www.cnblogs.com/czhwust/p/Win10_file.html
        HttpClient httpClient = new HttpClient();
        httpClient.DefaultRequestHeaders.Add("user-agent", "Mozilla/5.0 (compatible;MSIE 10.0;Windows NT 6.2;WOW64;Trident/6.0)");
        if (String.IsNullOrEmpty(tbUrl.Text))
        {
            tbstatus.Text = "输入的URL为空";
        }
        else
        {
            try
            {
                tbstatus.Text = " 等待响应......";
                HttpResponseMessage response = await httpClient.GetAsync(new Uri(tbUrl.Text));
                response.EnsureSuccessStatusCode();//确保请求成功
                tbstatus.Text = response.StatusCode + " " + response.ReasonPhrase;
                //请求图片                
                BitmapImage bitmap = new BitmapImage();
                //   WriteToStreamAsync
                using (InMemoryRandomAccessStream stream = new InMemoryRandomAccessStream())
                {
                    await response.Content.WriteToStreamAsync(stream);
                    stream.Seek(0ul);
                    bitmap.SetSource(stream);
                    img.Source = bitmap;
                }
                //         IInputStream   >>  IRandomAccessStream
                //IInputStream inputStream = await response.Content.ReadAsInputStreamAsync();
                //using (IRandomAccessStream randomAccessStream = new InMemoryRandomAccessStream())
                //{
                //    using (IOutputStream outputStream = randomAccessStream.GetOutputStreamAt(0))
                //    {
                //        await RandomAccessStream.CopyAsync(inputStream, outputStream);
                //        randomAccessStream.Seek(0);
                //        bitmap.SetSource(randomAccessStream);
                //        img.Source = bitmap;
                //    }
                //}
                //          IBuffer  >> IRandomAccessStream
                //IBuffer buffer = await response.Content.ReadAsBufferAsync();
                //using (IRandomAccessStream randomAccessStream = new InMemoryRandomAccessStream())
                //{
                //    using (DataWriter datawriter = new DataWriter(randomAccessStream.GetOutputStreamAt(0)))
                //    {
                //        datawriter.WriteBuffer(buffer, 0, buffer.Length);
                //        await datawriter.StoreAsync();
                //        randomAccessStream.Seek(0);
                //        bitmap.SetSource(randomAccessStream);
                //        img.Source = bitmap;
                //    }
                //}
            }
            catch (Exception ex)
            {
                tbstatus.Text = ex.ToString();
            }
        }
    }

 Socket通信

  Socket通信是一种点对点的通信技术,我们可以利用它开发点对点交互通信的软件。作为一种常见的底层网络通信技术,Socket具有简单易用、连接稳定、数据传送能力强等特点。HTTP通信是一种临时的,无状态的通信,在客户端发出HTTP请求,服务端做出一次响应之后,HTTP连接就会断开,当我们希望获取新的数据时,只能再发送一次HTTP请求,而Socket通信则是以IP地址和端口号为连接的一个通信句柄,以端到端为通信模型的网络通信协议。Socket能够保证连接的持久性,一旦与服务器成功建立连接,服务器相应的端口将会处于开放状态,此时客户端能够通过Socket建立的通道,向服务器开放的端口发出操作指令,而客户端同时也能得到服务端即时反馈的信息,直到程序发出断开指令或网络断开,Socket才会结束整个连接过程。

  Socket通信支持两种工作模式。一种是基于TCP模式,该模式是面向连接的,顺序进行的可靠交付方式,另一种是UDP模式,它是无连接的,资源消耗少的不可靠交付方式。关于二者更详细的区别,请自行百度了解。在UWP中Socket通信相关的类位于Windows.Networking.Sockets命名空间下,StreamSocket类对应于UDP,DatagramSocket类对应TCP。

  直接开始演示:

  首先,我们要完成服务端的编码,新建一个控制台应用程序。(贴出全部代码,不作过多解释。)   

 static void Main(string[] args)
    {
        int receiveLength;
        IPEndPoint ipEndPoint = new IPEndPoint(IPAddress.Any, 9900);
        Socket newSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream,ProtocolType.Udp);
        newSocket.Bind(ipEndPoint);
        newSocket.Listen(10);
        Console.WriteLine(" 等待客户端的连接 ");
        Socket client = newSocket.Accept();
        IPEndPoint clientIp = (IPEndPoint)client.RemoteEndPoint;
        Console.WriteLine(" 连接客户端地址 :" + clientIp.Address + ",端口号:" + clientIp.Port);
        while (true)
        {
            byte[] data = new byte[1024];
            receiveLength = client.Receive(data);
            Console.WriteLine(" 获取字符串的长度 " + receiveLength);
            if (receiveLength == 0)
                break;
            string getData = Encoding.UTF8.GetString(data, 0, receiveLength);
            Console.WriteLine(" 从客户端获得的数据 :" + getData);
            byte [] send = new byte[1024];
            send = Encoding.UTF8.GetBytes("response :" + getData);
            client.Send(send, send.Length, SocketFlags.None);
        }
        Console.WriteLine("Discnnected from " + clientIp.Address);
        client.Close();
        newSocket.Close();
    }

   然后就是客户端了,这里需要注意的是客户端在给服务端发消息时,同时读取了服务端发送给客户端的消息(服务端发给客户端的消息是 response:+客户端发来的消息)。  

private async void btnConnect_Click(object sender, RoutedEventArgs e)
    {
        try
        {
            socket = new StreamSocket();
            await socket.ConnectAsync(new HostName(tbIP.Text), tbPort.Text);//与服务端建立连接
            tbInfo.Text = " 连接成功";
        }
        catch (Exception ex)
        {
            tbInfo.Text = " 连接服务器错误:"+ex.ToString();
        }
    }
    private void btnClose_Click(object sender, RoutedEventArgs e)
    {
        //断开建立
        reader.Dispose();
        writer.Dispose();
        socket.Dispose();
        tbInfo.Text = " 关闭成功";
    }
    private void btnSend_Click(object sender, RoutedEventArgs e)
    {
        string str = tbMsg.Text;
        SendMsg(str,socket);//发送消息
    }
    private async void SendMsg(string str, StreamSocket socket)
    {
        try
        {
            //发送数据流
            writer = new DataWriter(socket.OutputStream);
            writer.WriteString(str);
            await writer.StoreAsync();
            //读取数据流
            reader = new DataReader(socket.InputStream);
            reader.InputStreamOptions = InputStreamOptions.Partial;
            await reader.LoadAsync(1024);
            string data = reader.ReadString(reader.UnconsumedBufferLength);
            tbReceivedMsg.Text += data + "\r\n";
        }
        catch (Exception ex)
        {
            tbInfo.Text = " 出现异常:"+ex.ToString();
        }
    }

     运行结果:

      

 WCF通信

  WCF(Windows Communication Foundation)也是一种重要的数据通信技术,它在.NET Framework 3.0中引入,主要优点在于服务集成,使分布式开发更加灵活稳定。客户端与WCF服务进行通信时需要借助代理,也就是添加服务引用。

  首先我们来完成WCF服务部分的编码,新建一个Visual C#语言的ASP.NET空Web应用程序。我们需要添加一个DataClass.cs的类文件和一个NewsDataService.svc的WCF服务文件。

DataClass.cs:

我们在添加[DataContract]时,可能无法导入命名空间,这时候我们要手动添加引用System.Runtime.Serialization,它的详细路径是 C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.5\System.Runtime.Serialization.dll

namespace WCFServer
{
[DataContract]
public  class DataClass
{
    [DataMember]
    public string NewsTime { set; get; }
    [DataMember]
    public string NewsTitle { get; set; }      
}
}
NewsDataService.svc:
public class NewsDataService : INewsDataService
{
   public DataClass [] News()
    {
        List<DataClass> newsData = new List<DataClass>()
        {
            new DataClass {NewsTitle="这是新闻标题1",NewsTime="2015-10-10" },
            new DataClass {NewsTitle="这是新闻标题2",NewsTime="2015-10-11" },
            new DataClass {NewsTitle="这是新闻标题3",NewsTime="2015-10-12" },
            new DataClass {NewsTitle="这是新闻标题4",NewsTime="2015-10-13" },
            new DataClass {NewsTitle="这是新闻标题5",NewsTime="2015-10-14" },
        };
        return newsData.ToArray();
    }
}

INewsDataService.cs:

namespace WCFServer
{
[ServiceContract]
public interface INewsDataService
{
    [OperationContract]
    DataClass[] News();
}
}

  然后是客户端部分的编码。首先我们要添加服务引用(右键”解决方案资源管理器“中的“引用”节点即可看到此选项),然后在下面的对话框中的“地址”输入WCF服务端的URI,点击“转到”,等加载完毕,自定义一个命名空间名称,点击“确定”即可,然后就可以在客户端调用服务器上的WCF服务了。

 

  我们首先得将服务端运行起来,客户端才能调用,在运行服务端时,可能我们直接运行项目,会报错(Forbidden),这时,我们可以选中NewsDataService.svc,然后右键,选择“在浏览器中查看”,出现上边右图的效果,ok!

客户端程序界面部分:

<Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
    <TextBlock x:Name="textBlock" HorizontalAlignment="Left" Margin="49,54,0,0" TextWrapping="Wrap" Text="WCF网络通信" VerticalAlignment="Top"/>
    <ListView x:Name="listView" HorizontalAlignment="Left" Height="266" Margin="49,118,0,0" VerticalAlignment="Top" Width="228">
        <ListView.ItemTemplate>
            <DataTemplate>
                <StackPanel Orientation="Horizontal">
                    <TextBlock Text="{Binding NewsTitle}"></TextBlock>
                    <TextBlock Text="{Binding NewsTime}"></TextBlock>
                </StackPanel>
            </DataTemplate>
        </ListView.ItemTemplate>
    </ListView>
    <Button x:Name="btn_getData" Content="获取数据" HorizontalAlignment="Left" Margin="49,409,0,0" VerticalAlignment="Top" Click="btn_getData_Click"/>
</Grid>

 后台代码:

private async void btn_getData_Click(object sender, RoutedEventArgs e)
    {
        NewsDataServiceClient client = new NewsDataServiceClient();
        ObservableCollection<DataClass> data = await client.NewsAsync();
        listView.ItemsSource = data;
    }

 运行效果:

 
    紧接着,我们再来看如何调用Web Service。这个其实和调用WCF服务差不多的,首先也是添加服务引用(http://webservice.webxml.com.cn/WebServices/MobileCodeWS.asmx),在http://webservice.webxml.com.cn这个网站上可以找到很多的Web Service供调用(不过好像经常打不开),然后这几行代码就OK

private async void btn_getData_Click(object sender, RoutedEventArgs e)
    {
        MobileCodeWSSoapClient client = new MobileCodeWSSoapClient();
        string result=await  client.getMobileCodeInfoAsync(tbTel.Text," ");
        txtresult.Text = result;
    }

   运行结果:

以上是小编为您精心准备的的内容,在的博客、问答、公众号、人物、课程等栏目也有的相关内容,欢迎继续使用右上角搜索按钮进行搜索windows
, 服务器
, string
new
windows网络编程教程、windows编程教程、windows编程视频教程、windows api编程教程、windows编程入门教程,以便于您获取更多的相关知识。

时间: 2024-11-03 06:29:54

Windows 10 开发 网络编程教程的相关文章

Windows 10开发基础——文件、文件夹和库(一)

原文:Windows 10开发基础--文件.文件夹和库(一) 主要内容:      1.枚举查询文件和文件夹      2.文本文件读写的三种方法--创建写入和读取文件      3.获得文件的属性   枚举查询文件和文件夹 先了解一下文件查询的几个方法: StorageFolder.GetFilesAsync: 获取当前文件夹中的所有文件,返回一个 IReadOnlyList<StorageFile>集合          IReadOnlyList<StorageFile> f

线程-windows 和 linux 网络编程文件传输

问题描述 windows 和 linux 网络编程文件传输 windows 两个线程,linux 两个进程,现在想传输一个文件,windows 这边其中的一个进程传一部分,剩下的由另外的一个进程来传.有什么好的方法吗?找了好多可是都没有相关的资料.谢谢大家. 解决方案 就是socket通信传递,windows做客户端,linux做服务端 解决方案二: Linux与Windows下文件传输windows到linux的文件传输linux 和 windows 文件传输

微软建议Windows 10开发人员升级到Visual Studio 2017

既然Visual Studio 2017已经发布,那就意味着微软开始专注于让其成为默认开发平台.Creators Update SDK的发布(面向即将到来的Windows 10 Creators Update)就是这种转变的一个很好的例子.该SDK只有Visual Studio 2017支持. 幸运的是,如果开发人员着眼于基于当前版本和将来版本的Windows 10开发系统,那么从这个版本的SDK开始,预览版SDK可以和当前生产版本的SDK并行安装.据微软Visual Studio项目经理Dan

iOS开发网络编程之断点续传_IOS

前言 网络下载是我们在项目中经常要用到的功能,如果是小文件的下载,比如图片和文字之类的,我们可以直接请求源地址,然后一次下载完毕.但是如果是下载较大的音频和视频文件,不可能一次下载完毕,用户可能下载一段时间,关闭程序,回家接着下载.这个时候,就需要实现断点续传的功能.让用户可以随时暂停下载,下次开始下载,还能接着上次的下载的进度. 今天我们来看看如何自己简单的封装一个断点续传的类,实现如下功能.     1.使用者只需要调用一个接口即可以下载,同时可以获取下载的进度.     2.下载成功,可以

ThinkPad笔记本Windows 10系统设置电池充电阈值教程

首先在应用商店安装Lenovo Settings程序,然后打开Lenovo Settings(设置中心),按照提示进行补丁包更新,打开Lenovo Settings,发现电池充电阈值的选项已经回归.     在设置中心中,会出现更改电池充电阈值的选项.     设置充电阈值的方法   1.左键点击屏幕右下角的"电池"图标,在出现的选项中,选择"转到 联想设置中心":     2.向下拖动进度条,找到"电池充电阈值"的选项:     3.打开&qu

Android 网络编程教程,基于socket和http协议实例

基于socket的用法 服务器端: 先启动一个服务器端的socket     ServerSocket svr = new ServerSocket(8989); 开始侦听请求 Socket s = svr.accept(); 取得输入和输出 DataInputStream dis = new DataInputStream(s.getInputStream()); DataOutputStream dos = new DataOutputStream(s.getOutputStream());

Windows 10设置默认浏览器的教程

1. 在windows10系统最下面的任务栏我们点击"所有设置"进入后找到下面的"系统"(显示,通知,应用,电源): 2. 接着在进入到的界面中我们再找到下面的"默认程序"点击它打开进入细节如下所示: 3. 点开浏览器"Web浏览器"可以根据需要,选择默认的浏览器. 好了设置好了这个就能直接使用它打开应用程序了,默认只要是使用浏览器打开的都是我们设置的默认浏览器了,当然如果更换不了看看是不是安装了电脑管家锁定了默认浏览器了,这

Python的requests网络编程包使用教程_python

早就听说requests的库的强大,只是还没有接触,今天接触了一下,发现以前使用urllib,urllib2等方法真是太搓了-- 这里写些简单的使用初步作为一个记录 一.下载 官方项目页: https://pypi.python.org/pypi/requests/#downloads 可以从上面直接下载. 二.发送无参数的get请求 >>> r = requests.get('http://httpbin.org/get') >>> print r.text { &q

基于Winsock API的VC网络编程实战

随着计算机信息技术的飞速发展,互联网与人类社会的工作.生活越来越紧密相关,它已 经成为人类获取.交流信息的重要途径和手段.所以当前对于开发人员来说,网络编程已是 必备的技能.本实例详细介绍了如何利用Winsock API编写网络应用程序. 一.实现 方法 在网络编程中最常用的方案便是Client/Server (客户机/服务器)模型.在这种 方案中客户应用程序向服务器程序请求服务.一个服务程序通常在一个众所周知的地址监听 对服务的请求,也就是说,服务进程一直处于休眠状态,直到一个客户向这个服务的