一、套接字(socket)概念

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

二、建立socket连接

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

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

三、服务端与客户端代码

1.服务端前台XMAL

<Window x:Class="WPFAPP.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:WPFAPP"
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>

2.服务端后台代码

using System;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Threading;
using System.Windows; namespace WPFAPP
{
/// <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("已经停止监听!");
}
}
}

3.客户端前台XMAL

<Window x:Class="WPFClient.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:WPFClient"
mc:Ignorable="d"
Title="客户端" Height="350" Width="525">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="50*"/>
<RowDefinition Height="50*"/>
<RowDefinition Height="200
*"/>
</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>

4.客户端后台代码

using System;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Threading;
using System.Windows; namespace WPFClient
{
/// <summary>
/// MainWindow.xaml 的交互逻辑
/// </summary>
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
this.IP.Text = "127.0.0.1";
this.Port.Text = "";
this.SentConnet.Text= @"发送消息";
}
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通信DEMO的更多相关文章

  1. 一个简单的Socket通信Demo

    服务器端Demo: Server.java(服务器端运行主程序,直接运行): package cn.wjs; import java.net.InetAddress; import java.net. ...

  2. [java]基于UDP的Socket通信Demo

    java课编程作业:在老师给的demo的基础上实现客户端发送数据到服务器端,服务器端接受客户端后进行数据广播. 整体功能类似于聊天室,代码部分不是太难,但是在本机测试的时候出现这样的问题: 服务端通过 ...

  3. TCP/IP Socket通信demo

    一个实例通过client端和server端通讯 客户端发送:“我是客户端,请多关照” 服务端回复:“收到来自于"+s.getInetAddress().getHostName()+" ...

  4. Android之从TCP/IP、HTTP看Socket通信

    1.概念 TCP/IP:属于传输层/网络层协议.手机能够使用联网功能是因为手机底层实现了TCP/IP协议,可以使手机终端通过无线网络建立TCP连接.TCP协议可以对上层网络提供接口,使上层网络数据的传 ...

  5. iOS开发之Socket通信实战--Request请求数据包编码模块

    实际上在iOS很多应用开发中,大部分用的网络通信都是http/https协议,除非有特殊的需求会用到Socket网络协议进行网络数 据传输,这时候在iOS客户端就需要很好的第三方CocoaAsyncS ...

  6. AgileEAS.NET SOA 中间件平台.Net Socket通信框架-简单例子-实现简单的服务端客户端消息应答

    一.AgileEAS.NET SOA中间件Socket/Tcp框架介绍 在文章AgileEAS.NET SOA 中间件平台Socket/Tcp通信框架介绍一文之中我们对AgileEAS.NET SOA ...

  7. 通信服务器群集——跨服务器通信Demo(源码)

    对于一些基于TCP Socket的大型C/S应用来说,能进行跨服务器通信可能是一个绕不开的功能性需求.出现这种需求的场景类似于下面描述的这种情况. 假设,我们一台TCP应用服务器能同时承载10000人 ...

  8. HTML5 Socket通信

    HTML5 Socket通信使用起来也是相当不从的,先将部分JS代码与大家分享: var socket; function connect() { var host = "ws://&quo ...

  9. Socket 通信原理(Android客户端和服务器以TCP&&UDP方式互通)

    转载地址:http://blog.csdn.net/mad1989/article/details/9147661 ZERO.前言 有关通信原理内容是在网上或百科整理得到,代码部分为本人所写,如果不当 ...

随机推荐

  1. linux - mysql - 忘记用户名、密码

    1, 关闭mysql服务 /etc/rc.d/init.d/mysqld stop 2,使用 –skip-grant-tables选项启动mysql服务 (1)打开文件 mysqld vi /etc/ ...

  2. 怎么把apk文件部署在云服务器上

    你服务器直接使用nginx,将请求映射到固定目录,把你的apk放到该目录.其他都不用干了.

  3. Winfrom控件 特效

    链接:https://pan.baidu.com/s/1O9e7sxnYFYWD55Vh5fxFQg 提取码:5cey 复制这段内容后打开百度网盘手机App,操作更方便哦 Winfrom控件查询手册. ...

  4. lua学习,笔者自用

    标识符与关键字A:常量用全大写和下划线,eg: My_ACCOUNTB: 变量的第一个字母小写,eg: strNumberC: 全局变量第一个字母用小写g表示,eg: gMyAcountD: 函数名第 ...

  5. 为mongoDB加用户权限管理

    MongoDB常用命令 > show dbs                  #显示数据库列表 > show collections        #显示当前数据库中的集合(类似关系数据 ...

  6. linux 中对 mysql 数据库的基本命令

    显示数据库列表 show databases; 显示库中的数据表 use mysql: // 打开库 show tables; 建库 create database 库名; 建库是设置好字符编码: c ...

  7. (转)http 之session和cookie

    http://www.cnblogs.com/xuxm2007/archive/2011/12/05/2276705.html Session简介 摘 要:虽然session机制在web应用程序中被采 ...

  8. kali linux2019.4安装启动后中文乱码

    1.鼠标右键找到黑框框打开终端 2.终端执行后重启,乱码解决. sudo apt-get install ttf-wqy-zenhei

  9. MySQL学习(十一)double write 介绍 (半原创)

    复习 Innodb关键的特性 插入缓存 两次写 异步IO 刷新邻近页 自适应哈希索引 概述 double write 的主要的作用是保证写入数据库文件的可靠性.通俗地说就是一份数据写两个地方,当出现异 ...

  10. vue中mixins的理解及应用

    vue中mixins的理解及应用 vue中提供了一种混合机制--mixins,用来更高效的实现组件内容的复用.最开始我一度认为这个和组件好像没啥区别..后来发现错了.下面我们来看看mixins和普通情 ...