一、套接字(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. Python模块导入详解

    定义 模块:用来从逻辑上组织Python代码(变量.函数.类.逻辑)去实现一个功能.本质就是.py结尾的Python文件. 包:用来从逻辑上组织模块的(可以放一堆模块在目录下).本质就是一个目录(必须 ...

  2. 关于EasyUI DataGrid行编辑时嵌入时间控件

    本人做一个名为“安徽中控”项目时,为快速开发基础数据增删改模块,遂采用EasyUIDatagrid将所有增删改查的操作都集中于表格中,并且所有增删改查操作都集中于泛型对象,从而不必为每个表写具体的增删 ...

  3. mysql 对数据的自增ID重新进行排序

    创建表格时添加: create table table1(id int auto_increment primary key,...) 创建表格后添加: 删除原有主键: ALTER TABLE `ta ...

  4. macaron 根目录默认为templates文件夹,所以如果启动目录同目录下有templates目录,要给它指定另一个文件夹

    m *macaron.Macaron //随便指向一个目录,因为web没用到模板,不能使用默认值templates,因为这个目录被其他模板占用了m.Use(macaron.Renderer(macar ...

  5. LED Holiday Light - Holiday Lighting Maintenance Guide

    If you are experiencing problems with LED holiday lighting, the following guides will provide advice ...

  6. [WC2006] 水管局长 - Link Cut Tree

    离线后逆序处理所有操作,那么就变成了加边询问,根据MST的性质,显然维护MST询问链上max即可 #include <bits/stdc++.h> using namespace std; ...

  7. SQL Server 2008创建数据库

    1.数据.数据库.数据管理系统基本概念: 数据:人类有用信息的符号化表示. 数据库:按照数据结构来组织.存储和管理数据的一个仓库. 数据库管理系统(DBMS):可维护.存储并为应用系统提供数据的软件系 ...

  8. PP: Reconstructing time series into a complex network to assess the evolution dynamics of the correlations among energy prices

    Purpose detect the dynamics in time series of their correlation Methodology 1. calculate correlation ...

  9. 快速将Navicat中数据表信息导出

    1.使用navicat工具  2.新建查询  SELECT COLUMN_NAME 字段名, COLUMN_TYPE 数据类型, DATA_TYPE 字段类型, CHARACTER_MAXIMUM_L ...

  10. Mybatis-对数据库的关联查询

            由于MyBatis逆向工程生成的代码只能进行对单表的操作(功能已经很强大了),但是远远不能满足开发的需要,下面就简单讲解下MyBatis进行关联查询的简单案例. 一.一对一关联查询 1 ...