客户端和服务端之间的通信(TCP)

和上篇的 客户端和服务端之间的通信(UDP)程序类似:http://www.cnblogs.com/Shang0109/archive/2012/07/29/2614176.html

     Socket最初应用于Unix当中,代表了一种文件描述符(在Unix中一切都是以文件为单位的)。在Windows当中则用于描述网路的访问,程序员通过Socket来发送和接收网路中的信息,因此我们可以把它理解为是一个跟网卡交互的API接口函数。

Socket访问网络的要素:

     1、本机的IP和Port端口(Socket只有与某一个IP和Port绑定,才能偶发挥强大的作用)

     2、必须指定通讯协议如:TCP和UDP。

在Internet上的主机一般运行了多个服务软件,同时提供几种服务。每种服务都打开一个Socket,并绑定到一个端口上,不同的端口对应于不同的服务

通过一个简单的实例来了解一下Socket在TCP协议下的基本通讯。

在程序当中使用到Socket时,需要首先添加“using System.Net; 和using System.Net.Sockets;” 两个引用

一、新建一个控制台应用程序:Server;

View Code
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Net;
using System.Net.Sockets;

namespace Server
{
    class Program
    {
        //1、要使用 Socket 发送和接收数据,必须首先使用 AddressFamily、SocketType 及 ProtocolType 创建它
        //2、SocketType 有时会隐式指示在 AddressFamily 中使用哪个 ProtocolType。例如,当 SocketType 为 Dgram 时,ProtocolType 始终为 Udp。
        //   当 SocketType 为 Stream 时,ProtocolType 始终为 Tcp。如果试图使用不兼容的组合创建 Socket,则 Socket 将引发 SocketException。

        static void Main(string[] args)
        {
            //第一步,定义一个Socket套接字
            Socket s = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
            //SocketType.Stream支持可靠、双向、基于连接的字节流,而不重复数据,也不保留边界。此类型的 Socket 与单个对方主机进行通信,并且在通信开始之前需要远程主机连接。Stream 使用传输控制协议 (Tcp) ProtocolType 和 InterNetworkAddressFamily。
            //AddressFamily.InterNetwork表示使用的IP地址是4段的,
            
            //第二步,绑定ip和端口
            IPEndPoint ipep = new IPEndPoint(IPAddress.Any, 9050);
            s.Bind(ipep);
            
            //第三步,通知TCP,服务器已经就绪
            s.Listen(0);//TCP是面向连接的,需要用Listen()方法监听一下网络上是否有人发送东西过来。
            //而UDP则不需要,UDP是无连接的,来者不拒。
            Console.WriteLine("服务器已启动!");

            //第四步,等待客户端的连接请求
            Socket client = s.Accept();
            //TCP情况下,如果监听到一个连接,就可以使用Accept()方法进行接收这个连接,然后执行Send()或者Receive()
            //UDP则不需要Accept(),直接用SendTo/ReceiveFrom来执行操作。
            //UDP不建立连接,所以发送前并不知道对方的IP和端口,因此需要指定一个发送的节点才能进行正常的发送和接收。(参照上篇UDP:http://www.cnblogs.com/Shang0109/archive/2012/07/29/2614176.html
            Console.WriteLine("有客户端:" + client.RemoteEndPoint.ToString() + "连接");
            
            byte[] recv = new byte[1024]; //定义一个byte类型的数组用于接收信息
            //接收客户端的信息,并保存到byte数组中(Receive()使用指定的 SocketFlags,从绑定的 Socket 接收数据,将数据存入接收缓冲区。)
            //SocketFlags:指定套接字的发送和接收行为。None:不对此调用使用标志。
            int bytes = client.Receive(recv, recv.Length, SocketFlags.None);
            //将byte数组转换成可读的string
            string receive = Encoding.ASCII.GetString(recv, 0, bytes);//进接收的信息转换成相应的字符串
            Console.WriteLine("接收到一条信息:" + receive);

            string sendString = "hello,this is a string from server";
            byte[] send = Encoding.ASCII.GetBytes(sendString);
            client.Send(send, send.Length, SocketFlags.None);

            client.Close();
            s.Close();//关闭套接字,服务停止
            Console.ReadLine();
        }
    }
}

二、新建一个控制台应用程序:Client;

View Code
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Net;
using System.Net.Sockets;

namespace Client
{
    class Program
    {
        static void Main(string[] args)
        {
            //客户端和服务端类似
            //第一步:建立套接字
            Socket s = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
            
            //第二步:将套接字于远程主机连接
            IPEndPoint ipep = new IPEndPoint(IPAddress.Parse("127.0.0.1"), 9050);//127.0.0.1指定本机的IP地址
            s.Connect(ipep);//连接服务器

            //第三步:发送信息
            string sendString = "this is a string to send";
            byte[] send = Encoding.ASCII.GetBytes(sendString);//将发送的信息转换成byte类型数组
            s.Send(send, send.Length, SocketFlags.None);

            byte[] recv = new byte[1024];
            int length = s.Receive(recv, recv.Length, SocketFlags.None);
            string receive = Encoding.ASCII.GetString(recv, 0, length);
            Console.WriteLine("从服务器端接收到一条信息:" + receive);

            s.Close();
            Console.ReadLine();
        }
    }
}

三、运行:先启动服务器,之后运行客户端程序。

原文地址:https://www.cnblogs.com/Shang0109/p/2620465.html