C# Socket通信简单实例


一、套接字(socket)概念

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

二、建立socket连接

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

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

服务端前台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("连接已经断开!"); } } }

 

 

转:https://www.cnblogs.com/TechnologyDictionary/archive/2019/02/22/10423068.html


免责声明!

本站转载的文章为个人学习借鉴使用,本站对版权不负任何法律责任。如果侵犯了您的隐私权益,请联系本站邮箱yoyou2525@163.com删除。



 
粤ICP备18138465号  © 2018-2025 CODEPRJ.COM