C#利用服务器实现客户端之间通信
这两天在学习C#,C#高级编程真的是厚厚的一本书QAQ。
昨天看了一下里面的通信部分(其实还没怎么看),看了网上一些人的博客,自己在他们的博客基础上写了一个通信。
先来讲述下我自己对于整个Socket通信过程的理解,毕竟初学,说错见谅,知道错了会改正~
首先在服务端新建一个serverSocket,对其进行初始化(一般包含AddressFamily:IP地址类型,SocketType:Socket传输数据方式,ProtoType:传输协议);
接着我们要设置server端要绑定的IP:port;然后开始监听,并设置最多同时监听多少个Client.
这时,服务端就在等待状态,直到某一个Client连接到这个ip:port上,这时serverSocket.Accept()工作,获得这个连接。(此时的连接是有地址信息的哦!记得保存)
获得连接之后,server就可以和这个Client进行通信了,当加入第二个Client(我们称其为ClientB)时,Server接收到ClientB的消息,可以将这个消息转发给前一个Client(我们称其为ClientA),当受到ClientA的消息,也可以转发给ClientB。这样就实现了Clients之间的通信了。(重点在保存连接信息!!)
那么现在贴上代码讲解:
Server端代码
namespace SocketServer
{
class Program
{
private static byte[] result = new byte[]; static Socket serverSocket;
private static string client;
private static Socket clientSocket;
//我这里存了两个Client,因为自己电脑开了两个Client,不会有多的
//理论上应该开一个Socket[]来保存信息,最好用一个二元组将client的信息和连接绑定起来
//这样就可以实现断开连接后下次登陆还是可以识别是这个Client
private static Socket clientSocketA=null;
private static Socket clientSocketB=null; static void Main(string[] args)
{
Program.SetPort();
}
private static void SetPort(int port)
{
IPAddress ip = IPAddress.Parse("127.0.0.1");//set ip
serverSocket = new Socket(AddressFamily.InterNetwork,
SocketType.Stream, ProtocolType.Tcp);//initialize
serverSocket.Bind(new IPEndPoint(ip, port));//bind
serverSocket.Listen();
//进入监听状态
Console.WriteLine("监听{0}成功", serverSocket.LocalEndPoint.ToString());
//开启一个线程来监听客户端连接
Thread myThread = new Thread(ListenClientConnect);
myThread.Start();
Console.ReadLine(); }
/// <summary>
/// 监听客户端连接
/// </summary>
private static void ListenClientConnect()
{
while (true)
{
//Client连接上后 得到这个连接
clientSocket = serverSocket.Accept(); //这里我因为只有两个Client,所以就简单写了
if (clientSocketA == null)
{
clientSocketA = clientSocket;
}
else if (clientSocketB == null)
{
clientSocketB = clientSocket;
}
else
{
//当其中一个断开了,又重新连接时,需要再次保存连接
if (clientSocketB.IsBound)
{
clientSocketA = clientSocketB;
clientSocketB = clientSocket;
}
else
{
clientSocketB = clientSocketA;
clientSocketA = clientSocket;
} }
clientSocket.Send(Encoding.ASCII.GetBytes("say hello"));
//开个线程接收Client信息
Thread receivedThread = new Thread(ReceiveMessage);
receivedThread.Start(clientSocket); }
} private static void ReceiveMessage(object clientSocket)
{
Socket myClientSocket = (Socket) clientSocket; while (true)
{
try
{
int revceiveNumber = myClientSocket.Receive(result);
//Console.WriteLine("接受客户端{0}消息{1}", myClientSocket.RemoteEndPoint.ToString()
// , Encoding.ASCII.GetString(result, 0, revceiveNumber));
Console.WriteLine(Encoding.ASCII.GetString(result, , revceiveNumber));
if (myClientSocket == clientSocketA)
{
Console.WriteLine("receive from A");
if (clientSocketB!=null&&clientSocketB.IsBound)
{
Console.WriteLine("a IS BOUND");
clientSocketB.Send(result, , revceiveNumber, SocketFlags.None);
}
else
{
myClientSocket.Send(Encoding.ASCII.GetBytes("the people is not online! Send Failed!"));
Console.WriteLine("对方不在线上,发送失败!");
}
}
else
{
Console.WriteLine("receive from B");
if (clientSocketA != null && clientSocketA.IsBound)
{
Console.WriteLine("a IS BOUND");
clientSocketA.Send(result, , revceiveNumber, SocketFlags.None);
}
else
{
myClientSocket.Send(Encoding.ASCII.GetBytes("the people is not online! Send Failed!"));
Console.WriteLine("对方不在线上,发送失败!");
} } }
catch(Exception ex)
{
Console.WriteLine(ex.Message);
myClientSocket.Shutdown(SocketShutdown.Both);
myClientSocket.Close();
break; }
} }
}
}
Client端代码(因为都差不多 就只贴一个了)
namespace SocketClient
{
class Program
{
private static byte[] result = new byte[];
private static Socket clientSocket;
private static void ListenServer()
{
while (true)
{
result = new byte[];
int receiveLength = clientSocket.Receive(result); Console.WriteLine("{0}", Encoding.ASCII.GetString(result, , receiveLength));
} }
static void Main(string[] args)
{ IPAddress ip = IPAddress.Parse("127.0.0.1");
clientSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
try
{
clientSocket.Connect(ip, );
Console.WriteLine("连接成功!"); }
catch (Exception e)
{
Console.WriteLine("连接失败!");
return;
}
Thread threadRead = new Thread(ListenServer);
threadRead.Start(); while(true)
{
try
{
Thread.Sleep();
string sendMessage = Console.ReadLine();
clientSocket.Send(Encoding.ASCII.GetBytes("Sylvia:"+sendMessage)); }
catch (Exception ex)
{
clientSocket.Shutdown(SocketShutdown.Both);
clientSocket.Close();
break;
} }
Console.WriteLine("发送完毕 按回车退出");
Console.ReadKey();
}
}
}
写的时候要特别注意一下Send信息的时候,注意byte[]的传输大小,很容易变成byte[]数组的大小而不是内容的大小。
这个大家就自己尝试吧
C#利用服务器实现客户端之间通信的更多相关文章
- 基于 HTML5 WebGL 的 3D 服务器与客户端的通信
这个例子的初衷是模拟服务器与客户端的通信,我把整个需求简化变成了今天的这个例子.3D 机房方面的模拟一般都是需要鹰眼来辅助的,这样找产品以及整个空间的概括会比较明确,在这个例子中我也加了,这篇文章就算 ...
- Node学习笔记:建立TCP服务器和客户端之间的通信
结构: socket是应用层和传输层的桥梁.(传输层之上的协议所涉及的数据都是在本机处理的,并没进入网络中) 涉及数据: socket所涉及的数据是报文,是明文. 作用: 建立长久链接,供网络上的两个 ...
- Redis服务器和客户端的通信
Redis客户端使用RESP(Redis序列化协议)与Redis服务器进行通信,RESP在位于TCP之上,而网络模型上客户端和服务器是保持的双工的连接.如图1 而一个简单的请求/响应的串行通信模型如下 ...
- Socket通信——服务器和客户端相互通信
所谓socket通常也称作"套接字",用于描述IP地址和端口,是一个通信链的句柄.应用程序通常通过"套接字"向网络发出请求或者应答网络请求. Socket和S ...
- [socket编程] 一个服务器与多个客户端之间通信
转自:http://blog.csdn.net/neicole/article/details/7539444 并加以改进 Server程序: // OneServerMain.cpp #includ ...
- ajax利用json进行服务器与客户端的通信
1.JQuery中$.ajax()方法参数详解 http://blog.sina.com.cn/s/blog_4f925fc30100la36.html 2.服务器端获取String que=requ ...
- Node学习笔记2:建立HTTP服务器和客户端之间的通信
http服务器端: var http = require('http'); var server = http.createServer(); server.on('request', functio ...
- 在Android上实现SSL握手(客户端需要密钥和证书),实现服务器和客户端之间Socket交互
Android的私钥和信任证书的格式必须是BKS格式的,通过配置本地JDK,让keytool可以生成BKS格式的私钥和信任证书,java本身没有BouncyCastle密库 服务端: Java代码 ...
- nodejs+expressjs+ws实现了websocket即时通讯,服务器和客户端互相通信
nodejs代码 // 导入WebSocket模块: const WebSocket = require('ws'); // 引用Server类: const WebSocketServer = We ...
随机推荐
- 【C# 进阶】事件!直接上事件!
http://www.tracefact.net/csharp-programming/delegates-and-events-in-csharp.aspx ZiYang 张,何许人也?看了他写的博 ...
- Unit01: JAVA开发环境
Top JAVA开发环境 1. JAVA开发环境 1.1. 认识Linux操作系统 1.1.1. Linux的由来及发展 Linux起源于1991年,1995年流行起来,大家可以看到旁边的这个人,它就 ...
- linux Centos下搭建gitolite服务器
1.安装git sudo yum install git -y 2.添加git管理账号 sudo adduser git 3.将gitolite克隆到本地,并安装 sudo mkdir /var/gi ...
- 提供一个表单,进行post数据处理
var strContent = "aaaaa"; html.Append("<html><body><form id='postUploa ...
- Foundation框架
1.框架是由许多类.方法.函数.文档按照一定的逻辑组织起来的集合,以便使研发程序变的更容易 清除缓存,删除这个文件夹下的所有文件/Users/fanyafang/Library/Developer/X ...
- Jquery EeasyUI等框架中图标的处理方法
在使用Query EasyUI.Ext等框架开发项目的时候,经常会用到很多小的图标,常见几个图片应用方式总结如下: 一.在jQuery Easyui中添加小图标 1.添加图标的两小步: 先到theme ...
- ios学习-控制按钮图片的走动和变换
一.项目要求:制作一个界面,通过点击按钮来控制头像(按钮)向上,向下,向左,向右移动,可以左旋转,右旋转,以及放大和缩小. 二.开发步骤: 1.通过拖动按钮到storyboard搭建UI界面(后面会写 ...
- jQuery属性操作
jQuery 的属性操作的核心部分其实就是对底层 getAttribute().setAttributes()等方法的一系列兼容性处理 ...if ( notxml ) { name = name.t ...
- WCF、MongoDB
http://www.cnblogs.com/quietwalk/archive/2011/08/09/2132573.html http://www.cnblogs.com/huangxinchen ...
- tensorflow 学习笔记
tensorflow一些函数: 1.tf.ones(shape,type=tf.float32,name=None) tf.ones([2, 3], int32) ==> [[1, 1 ...