一、socket简介

  socket就是套接字,它是引用网络连接的特殊文件描述符,由三个基本要素组成:

    1: AddressFamily(网络类型)

    2: SocketType(数据传输类型)

    3:ProtocolType(采用的网络协议)

  下面是可用于IP通信的套接字组合及其常用的属性和方法

二、socket与网络通信 

  IP连接领域有两种通信类型:面向连接的和无连接的,这里我要讲的是面向连接的,使用TCP协议来建立两个IP的值端点之间的会话,下面是它的基本步骤。

    a:建立一个套接字

    b:绑定本机的IP和端口

    c:使用listen()方法监听别人发过来的东西

    d:如果监听到连接,则可以使用Send/Receive来执行操作

    e:完成后使用Close()方法进行关闭

  工作原理如图所示:

  

三、一个简单的同步通信示例

  下面的例子中,服务器向所有连接的客户端发送消息,实现多播功能

using System;
using System.Collections.Generic;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Threading; namespace ServerFinally
{
class Program
{
//定义两个链表,分别存储连接的客户端和断开的客户端信息类
//并不是一个socket,而是自己写的一个辅助类
public static List<ClientCon> connectSockets = new List<ClientCon>();
public static List<ClientCon> disConnectSockets = new List<ClientCon>();
static void Main(string[] args)
{
//通过dns类获取本机ip地址(也可以直接输入IP地址)
IPHostEntry ipHostInfo = Dns.GetHostEntry(Dns.GetHostName());
IPAddress ipaddress = ipHostInfo.AddressList[];
IPEndPoint ipe = new IPEndPoint(ipaddress, ); Socket listener = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); try
{
listener.Bind(ipe);
listener.Listen(); //死循环 一直等待客户端连接
while (true)
{
Console.WriteLine("Wait for a connnect...");
Socket client = listener.Accept(); //阻塞当前线程
Console.WriteLine("A client is connct..."); //每次连接一个客户端,将其加入链表
ClientCon clientCon = new ClientCon(client);
connectSockets.Add(clientCon); //开启线程调用接受消息方法,一直接受消息
Thread t = new Thread(clientCon.ReceiveMessage);
t.Start(); Console.WriteLine("Start receive");
}
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
} //广播消息,将信息发送至所有已连接的客户端
public static void BroadcastMessage(string data)
{
foreach (ClientCon client in connectSockets)
{
//判断链表中的客户端是否已经断开,未断开连接就向其发送消息,否则从中移除
if (client.IsConnected)
{
client.SendMessage(data);
}
else
{
disConnectSockets.Add(client);
}
} foreach (ClientCon disConnect in disConnectSockets)
{
connectSockets.Remove(disConnect);
}
}
}
}

服务端

using System;
using System.Collections.Generic;
using System.Net.Sockets;
using System.Text; namespace ServerFinally
{
/// <summary>
/// 客户端连接辅助类
/// </summary>
class ClientCon
{
Socket client; //判断当前客户端是否断开连接
public bool IsConnected
{
get;
set;
} //构造函数 调用的时候为cliet赋值
public ClientCon(Socket s)
{
client = s;
IsConnected = true;
} //接受客户端发送的信息
public void ReceiveMessage()
{
byte[] buffer = new byte[];
string data = ""; while (true)
{
try
{
//判断客户端是否断开连接
if (!client.Poll(, SelectMode.SelectRead))
{
int length = client.Receive(buffer);
data = Encoding.UTF8.GetString(buffer, , length);
if (data != "")
{
Console.WriteLine("Receive message is :" + data);
Program.BroadcastMessage(data);
}
}
else
{
IsConnected = false;
Console.WriteLine("A client is disconnect");
break;
}
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
}
} //发送消息
public void SendMessage(string data)
{
byte[] buffer = new byte[];
buffer = Encoding.UTF8.GetBytes(data);
client.Send(buffer);
}
}
}

服务器端辅助类

using System;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Threading; namespace ClientFinally
{
class Program
{
static Socket client;
static Thread t;
static void Main(string[] args)
{
//通过IP地址和端口定义一个IPEndPoint类
IPEndPoint ipe = new IPEndPoint(IPAddress.Parse("10.128.119.68"), );
client = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); try
{
//连接服务器
client.Connect(ipe);
Console.WriteLine("Connnect to {0}", client.RemoteEndPoint.ToString()); //开启线程 接收消息
t = new Thread(ReceiveMessage);
t.Start(); //通过死循环发送消息
while (true)
{
byte[] bytes = new byte[];
Console.WriteLine("Please input you message:");
string mes = Console.ReadLine(); //如果输入的内容为空 关闭此客户端
if (mes == "")
{
client.Shutdown(SocketShutdown.Both);
client.Close();
break;
}
bytes = Encoding.UTF8.GetBytes(mes); //发送消息
client.Send(bytes);
}
}
catch (Exception e)
{
Console.WriteLine(e.Message);
}
} //接收消息
private static void ReceiveMessage()
{
while (true)
{
try
{
byte[] buffer = new byte[];
//length为接收信息长度
int length = client.Receive(buffer);
if (length > )
{
Console.WriteLine("receive message:" + Encoding.UTF8.GetString(buffer));
}
}
catch
{
break;
}
}
}
}
}

客户端代码

先启动服务器端,在启动客户端,效果如下

c#socket TCP同步网络通信的更多相关文章

  1. 程序猿修仙之路--数据结构之你是否真的懂数组? c#socket TCP同步网络通信 用lambda表达式树替代反射 ASP.NET MVC如何做一个简单的非法登录拦截

    程序猿修仙之路--数据结构之你是否真的懂数组?   数据结构 但凡IT江湖侠士,算法与数据结构为必修之课.早有前辈已经明确指出:程序=算法+数据结构  .要想在之后的江湖历练中通关,数据结构必不可少. ...

  2. C# 的TCP Socket (同步方式)

    简单的c# TCP通讯(TcpListener) C# 的TCP Socket (同步方式) C# 的TCP Socket (异步方式) C# 的tcp Socket设置自定义超时时间 C# TCP ...

  3. 27.Socket,TCP,UDP,HTTP基本通信原理

    Socket,TCP,UDP,HTTP基本通信原理(摘自百度): TCP.UDP,HTTP 底层通信都是通过 socket 套接字实现 网络上不同的计算机,也可以通信,那么就得使用网络套接字(sock ...

  4. TCP同步与异步,长连接与短连接【转载】

    原文地址:TCP同步与异步,长连接与短连接作者:1984346023 [转载说明:http://zjj1211.blog.51cto.com/1812544/373896   这是今天看到的一篇讲到T ...

  5. 分布式消息总线,基于.NET Socket Tcp的发布-订阅框架之离线支持,附代码下载

    一.分布式消息总线以及基于Socket的实现 在前面的分享一个分布式消息总线,基于.NET Socket Tcp的发布-订阅框架,附代码下载一文之中给大家分享和介绍了一个极其简单也非常容易上的基于.N ...

  6. 分享一个分布式消息总线,基于.NET Socket Tcp的发布-订阅框架,附代码下载

    一.分布式消息总线 在很多MIS项目之中都有这样的需求,需要一个及时.高效的的通知机制,即比如当使用者A完成了任务X,就需要立即告知使用者B任务X已经完成,在通常的情况下,开发人中都是在使用者B所使用 ...

  7. 重新想象 Windows 8 Store Apps (62) - 通信: Socket TCP, Socket UDP

    [源码下载] 重新想象 Windows 8 Store Apps (62) - 通信: Socket TCP, Socket UDP 作者:webabcd 介绍重新想象 Windows 8 Store ...

  8. 关于socket tcp 断线重连

    这个问题困扰过我几次,都没有来得及研究,今天研究一下. 首先写一个最简易的socket tcp程序,连接成功后再关闭服务器然后再用客户端各种操作看是什么情况 测试表明 (1)客户端已经连接,当服务端关 ...

  9. ActionScript简单实现Socket Tcp应用协议分析器

    转自..smark http://www.cnblogs.com/smark/archive/2012/05/15/2501507.html ActionScript简单实现Socket Tcp应用协 ...

随机推荐

  1. Alwayson--配置只读请求

    场景:有三台服务器SQLNode131,SQLNode132 ,SQLNode133: 1) 三台服务器加入域DCDemo.com 2) 三台服务器使用端口访问数据库 3) 三台服务器构建故障转移群集 ...

  2. jvm linux 时区设置

    # 背景 在接入集团一个平台的时候,发现录制某个接口到测试环境回放,发现接口入参一致,一个start_day 一个end_day,但回放的时候会多调用一次数据库查询,很是奇怪: 查阅业务代码,发现确实 ...

  3. MongoDB与SqlSugar与Ado.Net对比

    SqlSugar NET 4.+ & .NET CORE 高性能 轻量级 ORM框架,众多.NET框架中最容易使用的数据库访问技术 MongoDB与MySql的安装省略...虽然遇到了一些意外 ...

  4. 自定义两个控件,一个是显示图标和文字的矩形,一个是带边框的label(但是不是label)

    记录遇到的两个坑 坑1. 一开始我继承button 来实现下面的控件1,后面发现button没有双击事件.就改成继承UserControl了.重新编译,导致设计时的控件文本全部被清空,因为UserCo ...

  5. BitMap算法详解

    所谓的BitMap就是用一个bit位来标记某个元素所对应的value,而key即是该元素,由于BitMap使用了bit位来存储数据,因此可以大大节省存储空间. 基本思想: 这此我用一个简单的例子来详细 ...

  6. class字节码结构(三)(字段集合的结构)

    <Java虚拟机原理图解>1.4 class文件中的字段表集合--field字段在class文件中是怎样组织的 字段区:包括了字段计数器和字段数据区: 字段是指在类中定义的静态或者非静态的 ...

  7. iOS 中长按手势回调会被触发过两次

    Long-press gestures are continuous. The gesture begins (UIGestureRecognizerStateBegan) when the numb ...

  8. Python小白学习之路(九)—【字符串格式化】【百分号方式】【format方式】

    写在前面: 最近的事情好像有很多.李咏的离去,让我觉得很突然,仿佛印象中就是主持节目的他,看着他和哈文的爱情,很是感动.离去,没有什么抱怨,只是遗憾. 总会感慨,时光的流逝. 好像真的很快,转眼间,我 ...

  9. 【bzoj2789】 Letters 树状数组

    又是一道树状数组求逆序对的题目. 这一题我们可以将第二个串中的每一个字母,与第一个串中的字母做两两匹配,令第二个串第i个字母的值id[i]为该字母与第一个串中的字母匹配到的位置. 然后考虑到所求答案为 ...

  10. CentOS7启动Tomcat报错:./startup.sh: Permission denied

    错误信息:./startup.sh: Permission denied 执行./startup.sh,或者./shutdown.sh的时候, 报:Permission denied,因为是执行tom ...