一、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. NetCore入门篇:(四)Net Core项目启动文件Startup

    一.Startup介绍 1.Startup文件是Net Core应用程的启动程序,实现全局配置. 2.Net Core默认情况下,静态文件及Session都未启动,需要在Startup文件配置启动,否 ...

  2. 构建NetCore应用框架之实战篇(四):BitAdminCore框架1.0登录功能细化及技术选型

    本篇承接上篇内容,如果你不小心点击进来,建议从第一篇开始完整阅读,文章内容继承性连贯性. 构建NetCore应用框架之实战篇系列 一.BitAdminCore框架1.0版本 1.1.0版本是指最小版本 ...

  3. AOP面向切面的基石——动态代理(一)

    其实动态代理在Java里不是什么新技术了,早在java 1.2之后便通过 java.lang.reflect.InvocationHandler 加入了动态代理机制. 下面例子中,LancerEvol ...

  4. 获取分组后统计数量最多的纪录;limit用法;sql执行顺序

    CREATE TABLE emp(id INT PRIMARY KEY,NAME VARCHAR(11),dep_id INT ,salary INT); CREATE TABLE dept(id I ...

  5. 七,mysql优化——表的垂直划分和水平划分

    1,表的水平划分 如果一个表的记录数太多,比如成千上万条,而且需要经常检索,那么我们有必要化整为零.如果我拆成100个表,那么每个表只有10万条记录.当然需要数据在逻辑上可以划分.一个好的划分依据,有 ...

  6. 读懂Netty的高性能架构之道

    Netty是一个高性能.异步事件驱动的NIO框架,它提供了对TCP.UDP和文件传输的支持,作为一个异步NIO框架,Netty的所有IO操作都是异步非阻塞的,通过Future-Listener机制,用 ...

  7. react native 学习之 native modules

    翻译自https://facebook.github.io/react-native/docs/native-modules-ios.html Native Modules 很多情况下,app需要使用 ...

  8. ffmpeg + nginx 搭建流媒体

    //安装nginx rtmp 流媒体服务 1.安装nginx+rtmp模块  brew install nginx-full --with-rtmp-module 2.修改配置文件 /usr/loca ...

  9. WebDriverAPI(3)

    获取页面的Title属性 被测网址http:http://www.baidu.com Java语言版本的API实例代码 String url = "http://www.baidu.com& ...

  10. java语言编程入门

    1 概述 1.1 计算机 计算机包括硬件和软件两部分.硬件包括计算机中可以看得见的物理部分.软件提供看不见的指令.这些指令控制硬件并且使得硬件完成特定的任务. 1.2 程序设计 定义:创建(或开发软件 ...