简单的C# Socket通信实例

一、套接字(socket)概念

       套接字(socket)是通信的基石,是支持TCP/IP协议的网络通信的基本操作单元。它是网络通信过程中端点的抽象表示,包含进行网络通信必须的五种信息:连接使用的协议,本地主机的IP地址,本地进程的协议端口,远地主机的IP地址,远地进程的协议端口。
  应用层通过传输层进行数据通信时,TCP会遇到同时为多个应用程序进程提供并发服务的问题。多个TCP连接或多个应用程序进程可能需要通过同一个 TCP协议端口传输数据。为了区别不同的应用程序进程和连接,许多计算机操作系统为应用程序与TCP/IP协议交互提供了套接字(Socket)接口。应 用层可以和传输层通过Socket接口,区分来自不同应用程序进程或网络连接的通信,实现数据传输的并发服务。

二、建立socket连接

       建立Socket连接至少需要一对套接字,其中一个运行于客户端,称为ClientSocket ,另一个运行于服务器端,称为ServerSocket 。
  套接字之间的连接过程分为三个步骤:服务器监听,客户端请求,连接确认。

  1. 服务器监听:服务器端套接字并不定位具体的客户端套接字,而是处于等待连接的状态,实时监控网络状态,等待客户端的连接请求 
  2. 客户端请求:指客户端的套接字提出连接请求,要连接的目标是服务器端的套接字。为此,客户端的套接字必须首先描述它要连接的服务器的套接字,指出服务器端套接字的地址和端口号,然后就向服务器端套接字提出连接请求。
  3. 连接确认:当服务器端套接字监听到或者说接收到客户端套接字的连接请求时,就响应客户端套接字的请求,建立一个新的线程,把服务器端套接字的描述发给客户 端,一旦客户端确认了此描述,双方就正式建立连接。而服务器端套接字继续处于监听状态,继续接收其他客户端套接字的连接请求。

三、SOCKET连接与TCP连接

创建Socket连接时,可以指定使用的传输层协议,Socket可以支持不同的传输层协议(TCP或UDP),当使用TCP协议进行连接时,该Socket连接就是一个TCP连接。

五、Socket服务端与客户端通信示意图

六、服务端与客户端代码

服务端前台XMAL

<Window x:Class="Socket通信.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:Socket通信"
        mc:Ignorable="d"
        Title="服务端" Height="350" Width="525" Loaded="Window_Loaded" >
    <Grid>
        <Grid.RowDefinitions>
            <RowDefinition Height="50*"/>
            <RowDefinition Height="190*"/>
            <RowDefinition Height="81*"/>
        </Grid.RowDefinitions>
        <Grid Grid.Row="0">
            <WrapPanel VerticalAlignment="Center">
                <Label Padding="5">IP:</Label>
                <TextBox Padding="3" Width="150" Name="IP"></TextBox>
                <Label Padding="5">Port:</Label>
                <TextBox Padding="3" Width="100" Name="Port"></TextBox>
                <Button Padding="3" Margin="3" Click="Start_View_Click">开始监听</Button>
                <Button Padding="3" Margin="3" Click="Stop_Click">停止监听</Button>
            </WrapPanel>
        </Grid>
        <Grid Grid.Row="1">
            <ListBox Name="ListConnet"></ListBox>
        </Grid>
        <Grid Grid.Row="2">
            <Grid.ColumnDefinitions>
                <ColumnDefinition Width="405*"/>
                <ColumnDefinition Width="113*"/>
            </Grid.ColumnDefinitions>
           
                <TextBox Name="SentConnet"></TextBox>
                <Button Grid.Column="1" Click="Send_Click">发送</Button>
         
        </Grid>
    </Grid>
</Window>

服务端后台代码

using System;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Threading;
using System.Windows;

 

namespace Socket通信
{
    /// <summary>
    /// MainWindow.xaml 的交互逻辑
    /// </summary>
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
        }
        Socket socketSend;
        private void Start_View_Click(object sender, RoutedEventArgs e)
        {
            try
             {
                //点击开始监听时 在服务端创建一个负责监听IP和端口号的Socket
                 Socket socketWatch = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
                 IPAddress ip = IPAddress.Any;                //创建对象端口
                 IPEndPoint point = new IPEndPoint(ip, Convert.ToInt32(Port.Text));
                 socketWatch.Bind(point);//绑定端口号
                 ShowMsg("监听成功!");
                 socketWatch.Listen(10);//设置监听
                 //创建监听线程
                  Thread thread = new Thread(Listen);
                  thread.IsBackground = true;
                  thread.Start(socketWatch);
            }
             catch { }

 

        }
 
        void Listen(object o)
         {
              try
              {
                 Socket socketWatch = o as Socket;
                  while (true)
                  {
                     socketSend = socketWatch.Accept();//等待接收客户端连接
                     ShowMsg(socketSend.RemoteEndPoint.ToString() + ":" + "连接成功!");
                    //开启一个新线程,执行接收消息方法
                     Thread r_thread = new Thread(Received);
                     r_thread.IsBackground = true;
                     r_thread.Start(socketSend);
                 }
             }
             catch { }
        }

 

         /// <summary>
          /// 服务器端不停的接收客户端发来的消息
          /// </summary>
          /// <param name="o"></param>
          void Received(object o)
          {
             try
             {
                  Socket socketSend = o as Socket;
                 while (true)
                  {
                      //客户端连接服务器成功后,服务器接收客户端发送的消息
                    byte[] buffer = new byte[1024 * 1024 * 3];
                      //实际接收到的有效字节数
                      int len = socketSend.Receive(buffer);
                      if (len == 0)
                      {
                          break;
                      }
                      string str = Encoding.UTF8.GetString(buffer, 0, len);
                      ShowMsg("接收到的客户端数据:" + socketSend.RemoteEndPoint + ":" + str);
                  }
              }
              catch { }
          }
          /// <summary>
          /// 服务器向客户端发送消息
          /// </summary>
          /// <param name="str"></param>
          void Send(string str)
             {
                 byte[] buffer = Encoding.UTF8.GetBytes(str);
                 socketSend.Send(buffer);
             }
 
         void ShowMsg(string msg)
         {
            Dispatcher.Invoke(() => { ListConnet.Items.Add(msg + "\r\n"); });
         }

 

        private void Send_Click(object sender, RoutedEventArgs e)
        {
            Send(SentConnet.Text.Trim());
        }

        private void Window_Loaded(object sender, RoutedEventArgs e)
        {
        }
        private void Stop_Click(object sender, RoutedEventArgs e)
        {
            socketSend.Close();
            ShowMsg("已经停止监听!");
        }
    }
}

客户端前台XMAL

<Window x:Class="Socket_Client.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:Socket_Client"
        mc:Ignorable="d"
        Title="客户端" Height="350" Width="525">
    <Grid>
        <Grid.RowDefinitions>
            <RowDefinition Height="50*"/>
            <RowDefinition Height="190*"/>
            <RowDefinition Height="81*"/>
        </Grid.RowDefinitions>
        <Grid Grid.Row="0">
            <WrapPanel VerticalAlignment="Center">
                <Label Padding="5">IP:</Label>
                <TextBox Padding="3" Width="150" Name="IP"></TextBox>
                <Label Padding="5">Port:</Label>
                <TextBox Padding="3" Width="100" Name="Port"></TextBox>
                <Button Padding="3" Margin="3" Click="Start_View_Click">连接</Button>
                <Button Padding="3" Margin="3" Click="Stop_Click">断开连接</Button>
            </WrapPanel>
        </Grid>
        <Grid Grid.Row="1">
            <TextBox Name="ListConnet"></TextBox>
        </Grid>
        <Grid Grid.Row="2">
            <Grid.ColumnDefinitions>
                <ColumnDefinition Width="405*"/>
                <ColumnDefinition Width="113*"/>
            </Grid.ColumnDefinitions>

 

            <TextBox Name="SentConnet"></TextBox>
            <Button Grid.Column="1" Click="Send_Click">发送</Button>

        </Grid>
    </Grid>
</Window>

客户端后台代码

using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;

 

namespace Socket_Client
{
    /// <summary>
    /// MainWindow.xaml 的交互逻辑
    /// </summary>
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
        }
        Socket socketSend;

 

        private void Start_View_Click(object sender, RoutedEventArgs e)
        {
            try
              {
                                //创建客户端Socket,获得远程ip和端口号
                    socketSend = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
                    IPAddress ip = IPAddress.Parse(IP.Text);
                    IPEndPoint point = new IPEndPoint(ip, Convert.ToInt32(Port.Text));
               
                    socketSend.Connect(point);
                    ShowMsg("连接成功!");
                                 //开启新的线程,不停的接收服务器发来的消息
                    Thread c_thread = new Thread(Received);
                    c_thread.IsBackground = true;
                    c_thread.Start();
               }
             catch (Exception)
            {
               ShowMsg("IP或者端口号错误...");
            }
           

 

        }
        void ShowMsg(string str)
         {

 

            Dispatcher.Invoke(() => { ListConnet.AppendText(str + "\r\n"); });
        }
        /// <summary>
         /// 接收服务端返回的消息
         /// </summary>
        void Received()
        {
            while (true)
            {
              try
              {
                   byte[] buffer = new byte[1024 * 1024 * 3];
                   //实际接收到的有效字节数
                    int len = socketSend.Receive(buffer);
                   if (len == 0)
                   {
                       continue;
                     }
                    string str = Encoding.UTF8.GetString(buffer, 0, len);
                    ShowMsg("接收到的服务端数据:" + socketSend.RemoteEndPoint + ":" + str);
                }
                catch
                {

 

                }
           }
        }

 

        private void Send_Click(object sender, RoutedEventArgs e)
        {
            try
            {
                     string msg = SentConnet.Text.Trim();
                     byte[] buffer = new byte[1024 * 1024 * 3];
                     buffer = Encoding.UTF8.GetBytes(msg);
                     socketSend.Send(buffer);
              }
            catch { }

 

        }

        private void Stop_Click(object sender, RoutedEventArgs e)
        {
            socketSend.Close();
            ShowMsg("连接已经断开!");
        }
    }
}

运行结果

 

 

 

 

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值