c#socket TCP同步网络通信
一、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同步网络通信的更多相关文章
- 程序猿修仙之路--数据结构之你是否真的懂数组? c#socket TCP同步网络通信 用lambda表达式树替代反射 ASP.NET MVC如何做一个简单的非法登录拦截
程序猿修仙之路--数据结构之你是否真的懂数组? 数据结构 但凡IT江湖侠士,算法与数据结构为必修之课.早有前辈已经明确指出:程序=算法+数据结构 .要想在之后的江湖历练中通关,数据结构必不可少. ...
- C# 的TCP Socket (同步方式)
简单的c# TCP通讯(TcpListener) C# 的TCP Socket (同步方式) C# 的TCP Socket (异步方式) C# 的tcp Socket设置自定义超时时间 C# TCP ...
- 27.Socket,TCP,UDP,HTTP基本通信原理
Socket,TCP,UDP,HTTP基本通信原理(摘自百度): TCP.UDP,HTTP 底层通信都是通过 socket 套接字实现 网络上不同的计算机,也可以通信,那么就得使用网络套接字(sock ...
- TCP同步与异步,长连接与短连接【转载】
原文地址:TCP同步与异步,长连接与短连接作者:1984346023 [转载说明:http://zjj1211.blog.51cto.com/1812544/373896 这是今天看到的一篇讲到T ...
- 分布式消息总线,基于.NET Socket Tcp的发布-订阅框架之离线支持,附代码下载
一.分布式消息总线以及基于Socket的实现 在前面的分享一个分布式消息总线,基于.NET Socket Tcp的发布-订阅框架,附代码下载一文之中给大家分享和介绍了一个极其简单也非常容易上的基于.N ...
- 分享一个分布式消息总线,基于.NET Socket Tcp的发布-订阅框架,附代码下载
一.分布式消息总线 在很多MIS项目之中都有这样的需求,需要一个及时.高效的的通知机制,即比如当使用者A完成了任务X,就需要立即告知使用者B任务X已经完成,在通常的情况下,开发人中都是在使用者B所使用 ...
- 重新想象 Windows 8 Store Apps (62) - 通信: Socket TCP, Socket UDP
[源码下载] 重新想象 Windows 8 Store Apps (62) - 通信: Socket TCP, Socket UDP 作者:webabcd 介绍重新想象 Windows 8 Store ...
- 关于socket tcp 断线重连
这个问题困扰过我几次,都没有来得及研究,今天研究一下. 首先写一个最简易的socket tcp程序,连接成功后再关闭服务器然后再用客户端各种操作看是什么情况 测试表明 (1)客户端已经连接,当服务端关 ...
- ActionScript简单实现Socket Tcp应用协议分析器
转自..smark http://www.cnblogs.com/smark/archive/2012/05/15/2501507.html ActionScript简单实现Socket Tcp应用协 ...
随机推荐
- asp.net core 的用户注册功能——Identity上手
首先请using这个类库. using Microsoft.AspNetCore.Identity; 这个类库老牛逼了,首先是包含了一个IdentityUser类.我们可以自己写一个User类继承Id ...
- DataTable根据字段去重
DataTable根据字段去重 最近需要对datatable根据字段去重,在网上搜了很多,找到了一个方法,代码如下 public static DataTable DistinctSomeColumn ...
- 开源一款强大的文件服务组件(QJ_FileCenter)(系列一)
系列文章 1. 开源一款强大的文件服务组件(QJ_FileCenter)(系列一) 2. 开源一款强大的文件服务组件(QJ_FileCenter)(系列二 安装说明) 3. 开源一款强大的文件服务组件 ...
- C博客作业03—函数
1.本章学习总结 1.1思维导图 1.2本章学习体会及代码量学习体会 1.2.1 学习体会 知道了程序的模块化设计可使程序结构清晰,简化复杂问题,解决代码重复问题 学会使用自定义函数简化主函数,使代码 ...
- 782. Transform to Chessboard
An N x N board contains only 0s and 1s. In each move, you can swap any 2 rows with each other, or an ...
- POJ 3468A Simple Problem with Integers(线段树区间更新)
A Simple Problem with Integers Time Limit: 5000MS Memory Limit: 131072K Total Submissions: 112228 ...
- badboy录制网站出现css样式混乱,网页的图标点击没反应
本人在测试web工作过程中,遇到了标题一样的问题.苦恼很久也没有找到原因.后面自己摸索,发现了问题所在! badboy安装是2.2.5版本:ie最新版本: 原因:首次安装badboy的时候,所默认的浏 ...
- POJ 1125
#include<iostream> #include<stdio.h> #define MAXN 102 #define inf 100000000 using namesp ...
- 添加或删除 HTML dom元素
添加或删除 HTML dom元素 创建新的 HTML 元素 如需向 HTML DOM 添加新元素,您必须首先创建该元素(元素节点),然后向一个已存在的元素追加该元素. <div id=" ...
- tensorflow进阶篇-4(损失函数1)
L2正则损失函数(即欧拉损失函数),L2正则损失函数是预测值与目标函数差值的平方和.L2正则损失函数是非常有用的损失函数,因为它在目标值附近有更好的曲度,并且离目标越近收敛越慢: # L = (pre ...