一、套接字(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="" Width="" Loaded="Window_Loaded" >
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="50*"/>
<RowDefinition Height="190*"/>
<RowDefinition Height="81*"/>
</Grid.RowDefinitions>
<Grid Grid.Row="">
<WrapPanel VerticalAlignment="Center">
<Label Padding="">IP:</Label>
<TextBox Padding="" Width="" Name="IP"></TextBox>
<Label Padding="">Port:</Label>
<TextBox Padding="" Width="" Name="Port"></TextBox>
<Button Padding="" Margin="" Click="Start_View_Click">开始监听</Button>
<Button Padding="" Margin="" Click="Stop_Click">停止监听</Button>
</WrapPanel>
</Grid>
<Grid Grid.Row="">
<ListBox Name="ListConnet"></ListBox>
</Grid>
<Grid Grid.Row="">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="405*"/>
<ColumnDefinition Width="113*"/>
</Grid.ColumnDefinitions> <TextBox Name="SentConnet"></TextBox>
<Button Grid.Column="" 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();//设置监听
//创建监听线程
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[ * * ];
//实际接收到的有效字节数
int len = socketSend.Receive(buffer);
if (len == )
{
break;
}
string str = Encoding.UTF8.GetString(buffer, , 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[ * * ];
//实际接收到的有效字节数
int len = socketSend.Receive(buffer);
if (len == )
{
continue;
}
string str = Encoding.UTF8.GetString(buffer, , len);
ShowMsg("接收到的服务端数据:" + socketSend.RemoteEndPoint + ":" + str);
}
catch
{ }
}
} private void Send_Click(object sender, RoutedEventArgs e)
{
try
{
string msg = SentConnet.Text.Trim();
byte[] buffer = new byte[ * * ];
buffer = Encoding.UTF8.GetBytes(msg);
socketSend.Send(buffer);
}
catch { } } private void Stop_Click(object sender, RoutedEventArgs e)
{
socketSend.Close();
ShowMsg("连接已经断开!");
}
}
}

运行结果

简单的C# Socket通信实例的更多相关文章

  1. Linux下简单的socket通信实例

    Linux下简单的socket通信实例 If you spend too much time thinking about a thing, you’ll never get it done. —Br ...

  2. Flex通信-与Java实现Socket通信实例

    Flex通信-与Java实现Socket通信实例  转自:http://blessht.iteye.com/blog/1136888 博客分类: Flex 环境准备 [服务器端] JDK1.6,“ja ...

  3. Java Socket 通信实例 - 转载

    基于Tcp协议的简单Socket通信实例(JAVA)   好久没写博客了,前段时间忙于做项目,耽误了些时间,今天开始继续写起~ 今天来讲下关于Socket通信的简单应用,关于什么是Socket以及一些 ...

  4. UEditor编辑器和php简单的实现socket通信

    一.UEditor编辑器 使用这个编辑器是需要先下载编辑器文件,记得下载的时候放入自己的网站中,既然是php中使用,自然我下载的就是php的UEditor编辑器了,然后是utf-8的 其实使用很简单, ...

  5. 网络协议栈学习(一)socket通信实例

    网络协议栈学习(一)socket通信实例 该实例摘自<linux网络编程>(宋敬彬,孙海滨等著). 例子分为服务器端和客户端,客户端连接服务器后从标准输入读取输入的字符串,发送给服务器:服 ...

  6. (8)Linux(客户端)和Windows(服务端)下socket通信实例

    Linux(客户端)和Windows(服务端)下socket通信实例: (1)首先是Windows做客户端,Linux做服务端的程序 Windows   Client端 #include <st ...

  7. 基于Tcp协议的简单Socket通信实例(JAVA)

    好久没写博客了,前段时间忙于做项目,耽误了些时间,今天开始继续写起~ 今天来讲下关于Socket通信的简单应用,关于什么是Socket以及一些网络编程的基础,这里就不提了,只记录最简单易懂实用的东西. ...

  8. Java Socket通信实例

    一.简单的客户端与服务器一对一连接: Socket通信的步骤: 1.创建ServerSocket和Socket 2.打开连接到Scket的输入/输出流 3.按照协议对Socket进行读/写操作 4.关 ...

  9. Linux C++ TCP Socket通信实例

    环境:Linux 语言:C++ 通信方式:TCP 下面用TCP协议编写一个简单的服务器.客户端,其中服务器端一直监听本机的6666号端口.如果收到连接请求,将接收请求并接收客户端发来的消息:客户端与服 ...

随机推荐

  1. python程序保存成二进制(不公开源码)

    https://www.tiobe.com/ (python语言排行榜) pip install pyinstaller pyinstaller test.py ./test

  2. canvas 实现太阳系效果

    一:创建画布 <canvas width="1000" height="1000" id="solar" style="ba ...

  3. idea运行项目时报Error:java无效的源发行版:1.8

    如果你安装的是JDK1.7,而在file->project structure中设置的是language level是8的话,就会出现这个错误提示:无效的源发行版:8. 解决办法:将语言级别改为 ...

  4. 2018.12.29 codeforces 940E. Cashback(线性dp)

    传送门 题意:给出一个nnn个数的序列,要求将序列分成若干段,对于一段长度为kkk的自动删去最小的⌊kc⌋\left \lfloor \frac{k}{c} \right \rfloor⌊ck​⌋个数 ...

  5. 2018.11.01 NOIP训练 某种密码(折半搜索)

    传送门 直接折半搜索,把所有和装到unorderedmapunordered_mapunorderedm​ap里面最后统计答案就行了. 然后考试的时候读优并没有处理有负数的情况于是爆零了 代码

  6. (13)How to stay calm when you know you'll be stressed

    https://www.ted.com/talks/daniel_levitin_how_to_stay_calm_when_you_know_you_ll_be_stressed/transcrip ...

  7. 学以致用十六-----Centos7.2编译安装mysql5.6.22

    一.系统环境 二.卸载系统自带的mariadb rpm -qa | grep db rpm -e --nodeps mariadb-libs-5.5.60 rpm -e --nodeps mariad ...

  8. [转]MySQL源码:Range和Ref优化的成本评估

    MySQL源码:Range和Ref优化的成本评估 原文链接:http://www.orczhou.com/index.php/2012/12/mysql-source-code-optimizer-r ...

  9. ActiveMQ实战之 Queue点对点消息

    前言:ActiveMQ消息模式点对点编码 运行:先运行消费者在开启消息生产者即可接收到消息 消息生产者 /** * @摘要 测试发送单条数据的类 */ public class ZMQOneSendT ...

  10. Update Node.js Package.json

    Update the latest package while using node.js, follow the command as following. npm i -g npm-check-u ...