C#TCP Socket网络编程(异步通信方式)

一、Socket编程

Socket即为套接字,它其实是一个句柄,存在于内存中的一个标识符,作为网络通信的一个符号。

Socket类位于System.Net.Sockets命名空间,封装了与套接字编程相关的API,其内部调用了与WInsock相关的WIn32 API。

网络通信至少有两个通信终端,一般来说,监听并接受连续的一端称为服务器,而发送请求的一方称为客户端。


二、Socket类的使用步骤

1、服务器

(1)实例化Socket对象。

Socket server = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);

(2)调用Bind方法绑定本地终结点。需要指定一个本地IP地址和一个本地端口,Socket将在该终结点上监听传入的客户端连接。(注意绑定饿端口号必须为系统暂未分配的,否则指定端口号无效,无法建立连接)

IPEndPoint endpoint = new IPEndPoint(IPAddress.Any, 8622);
server.Bind(endpoint);

(3)调用Listen方法开始监听客户端连接。

server.Listen(15);

(4)调用Accept相关方法接收连接,并返回一个用于与客户端进行通信的Socket实例。

server.BeginAccept(new AsyncCallback(Accpcallback), server);
private static void Accpcallback(IAsyncResult ar)
        {
            Socket server = (Socket)ar.AsyncState;
            Socket client = server.EndAccept(ar);
            string remoteendpoint = client.RemoteEndPoint.ToString();
            Console.WriteLine("已接受客户端【0】的连接。" + remoteendpoint);
            byte[] data = Encoding.UTF8.GetBytes("您好,服务器已经接受连接了。");
            int len = data.Length;
            client.Send(BitConverter.GetBytes(len));
            client.Send(data);
            client.Close();
            Console.ReadLine();
            server.BeginAccept(new AsyncCallback(Accpcallback), server);
        }

(5)通过Send方法和Recieve方法进行收发数据。

(6)通信结束后调用Close关闭Socket对象。

2、客户端

(1)实例化Socket。

Socket client = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);

(2)调用Connect方法进行连接,需要指定服务器的地址和端口,服务器的端口必须与服务器绑定的监听端口一致,否则无法连接。

client.Connect("127.0.0.1", 8622);

(3)调用Send和Recieve方法收发数据。对于未进行连接的Socket对象,可以使用RecieveFrom和SendTo来进行通信。

(4)通信结束后关闭Socket对象。

3、连接示意图

C#TCP Socket网络编程(异步通信方式)_第1张图片


三、服务器,客户端源代码

客户端:

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

namespace tcpclient
{
    class Program
    {
        static void Main(string[] args)
        {
            Socket client = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);

            try
            {
                client.Connect("127.0.0.1", 8622);
                string remoteendpoint = client.RemoteEndPoint.ToString();
                Console.WriteLine("成功连接服务器【0】。" + remoteendpoint);

                byte[] buffer = new byte[4];
                client.Receive(buffer);
                int len = BitConverter.ToInt32(buffer, 0);

                buffer = new byte[len];
                client.Receive(buffer);
                string msg = Encoding.UTF8.GetString(buffer);
                Console.WriteLine("从服务器接收到消息:\n" + msg);
                Console.ReadLine();
            }
            catch (SocketException ex)
            {
                Console.WriteLine(ex.Message);
            }
        }
    }
}

服务器

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

namespace tcpserver
{
    class Program
    {

        static void Main(string[] args)
        {
            
            Socket server = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
            IPEndPoint endpoint = new IPEndPoint(IPAddress.Any, 8622);
            server.Bind(endpoint);

            server.Listen(15);
            server.BeginAccept(new AsyncCallback(Accpcallback), server);
            Console.ReadLine();
        }

        private static void Accpcallback(IAsyncResult ar)
        {
            Socket server = (Socket)ar.AsyncState;
            Socket client = server.EndAccept(ar);
            string remoteendpoint = client.RemoteEndPoint.ToString();
            Console.WriteLine("已接受客户端【0】的连接。" + remoteendpoint);
            byte[] data = Encoding.UTF8.GetBytes("您好,服务器已经接受连接了。");
            int len = data.Length;
            client.Send(BitConverter.GetBytes(len));
            client.Send(data);
            client.Close();
            Console.ReadLine();
            server.BeginAccept(new AsyncCallback(Accpcallback), server);
        }
    }
}


源码下载地址:

http://download.csdn.net/detail/kevin_iot/9749747


注意:以上为两个项目,必须两个项目全部运行才能完成客户端与服务端的连接

如何同时建立两个项目?在已有的项目基础上,右键解决方案,新建新的项目。

如何同时运行多个项目?打开解决方案属性窗口,把启动方式改为“多启动项目”,并且将两个项目都标记为“启动”。

如何验证程序的执行步骤?设置断电,一步步执行,看执行步骤是否为示意图所示。


运行结果

C#TCP Socket网络编程(异步通信方式)_第2张图片


参考文章:

C#网络编程基本字段——IPAddress、IPEndPoint

C#编程笔记

C#Socket简单例子(服务器与客户端通信)

参考书籍:

C#6.0 学习笔记


你可能感兴趣的:(c#)