一、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. [Openwrt 项目开发笔记]:Openwrt平台搭建(一)补遗

    [Openwrt项目开发笔记]系列文章传送门:http://www.cnblogs.com/double-win/p/3888399.html 正文: 昨晚上熬夜写了[Openwrt项目开发笔记]:O ...

  2. [LeetCode 题解]: Binary Tree Preorder Traversal

    前言   [LeetCode 题解]系列传送门:  http://www.cnblogs.com/double-win/category/573499.html   1.题目描述 Given a bi ...

  3. Jesery客户端工具类

    public class JerseyClientUtil { public static<T> T sendMsg(String url,Object object,Class<T ...

  4. navicat远程连接oracle

    本机没有oracle,这个软件太大了. 想要远程连接oracle,本地不安装oracle的话是不行的,我们安装一个oracle instance client,然后配置navicat就ok了. 下载i ...

  5. 【TFS错误】TF30063: 您没有访问 Microsoft-IIS/8.5 的权限

    问题现象 开发人员报告,所有的生成都失败了,日志显示下载源代码出错,系统提示错误信息为"-TF30063: 您没有访问 Microsoft-IIS/8.5 的权限-". 图1 - ...

  6. ajax方式上传图片到Django后台

    参考价值最大 https://blog.csdn.net/huangql517/article/details/81259671 https://www.cnblogs.com/chenjianhon ...

  7. ASP.NET Core使用Elasticsearch记录NLog日志

    ASP.NET Core使用Elasticsearch记录NLog日志 1.新建一个 ASP.NET Core项目 2.安装Nuge包 运行:Install-Package NLog.Web.AspN ...

  8. log4j学习(一)最简单的例子

    前言: 之前笔者一直是在System.out中打日志的,由于笔者大部分时候是编写在tomcat容器里运行的一些个小web应用,所以这么做似乎没什么问题:打印出来的日志都可以在tomcat自己的log目 ...

  9. 日常一些出现bug的问题

    1.Fatal signal 4 (SIGILL), code 1, fault addr 0xca31569e in tid 8033 (r.myapplication) fault addr : ...

  10. django项目中使用项目环境制作脚本 通过终端命令运行脚本文件

    在实际的django项目开发中,有时候需要制作一些脚本文件对项目数据进行处理,然后通过终端命令运行脚本. 完整的实现流程如下: 1.在一个应用目录下(app, 必须是在应用目录下,可以专门创建一个应用 ...