这两天在学习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#利用服务器实现客户端之间通信的更多相关文章

  1. 基于 HTML5 WebGL 的 3D 服务器与客户端的通信

    这个例子的初衷是模拟服务器与客户端的通信,我把整个需求简化变成了今天的这个例子.3D 机房方面的模拟一般都是需要鹰眼来辅助的,这样找产品以及整个空间的概括会比较明确,在这个例子中我也加了,这篇文章就算 ...

  2. Node学习笔记:建立TCP服务器和客户端之间的通信

    结构: socket是应用层和传输层的桥梁.(传输层之上的协议所涉及的数据都是在本机处理的,并没进入网络中) 涉及数据: socket所涉及的数据是报文,是明文. 作用: 建立长久链接,供网络上的两个 ...

  3. Redis服务器和客户端的通信

    Redis客户端使用RESP(Redis序列化协议)与Redis服务器进行通信,RESP在位于TCP之上,而网络模型上客户端和服务器是保持的双工的连接.如图1 而一个简单的请求/响应的串行通信模型如下 ...

  4. Socket通信——服务器和客户端相互通信

    所谓socket通常也称作"套接字",用于描述IP地址和端口,是一个通信链的句柄.应用程序通常通过"套接字"向网络发出请求或者应答网络请求.  Socket和S ...

  5. [socket编程] 一个服务器与多个客户端之间通信

    转自:http://blog.csdn.net/neicole/article/details/7539444 并加以改进 Server程序: // OneServerMain.cpp #includ ...

  6. ajax利用json进行服务器与客户端的通信

    1.JQuery中$.ajax()方法参数详解 http://blog.sina.com.cn/s/blog_4f925fc30100la36.html 2.服务器端获取String que=requ ...

  7. Node学习笔记2:建立HTTP服务器和客户端之间的通信

    http服务器端: var http = require('http'); var server = http.createServer(); server.on('request', functio ...

  8. 在Android上实现SSL握手(客户端需要密钥和证书),实现服务器和客户端之间Socket交互

    Android的私钥和信任证书的格式必须是BKS格式的,通过配置本地JDK,让keytool可以生成BKS格式的私钥和信任证书,java本身没有BouncyCastle密库 服务端: Java代码  ...

  9. nodejs+expressjs+ws实现了websocket即时通讯,服务器和客户端互相通信

    nodejs代码 // 导入WebSocket模块: const WebSocket = require('ws'); // 引用Server类: const WebSocketServer = We ...

随机推荐

  1. 夺命雷公狗-----React_native---4---初始化项目

    我们首先在android目录下创建一个apps的文件夹: 然后我们在apps目录下,按住shift键加鼠标右键选择--在此打开命令窗口输入命令初始化项目 然后就是等了................. ...

  2. [原创]Visual Studio 使用 Just My Code引起无法断点

    今天遇到的问题,同样的代码,在一台机器上用Release配置可以命中断点,在另一台上用Release断点就都失效了.后来发现是因为断点失效的机器上设置了Just My Code.在Debug-Opti ...

  3. UVA 11624 BFS的妙用

    题意: 迷宫里起火了,有若干个障碍物,有多个起火点,起火点每经过一个时间间隔就向它的上下左右相邻的格子扩散. 有个倒霉的人好像叫做“Joe”,他要逃出来,他每次可以向上下左右任意移动一格,但是即要避开 ...

  4. iOS tableView 滚动后回到顶部

    - (void)scrollViewDidScroll:(UIScrollView *)scrollView { CGPoint contentOffsetPoint = self.tableView ...

  5. CSS 文字垂直居中

    原始 demo html <div class ="box"> <div class="text"> 我是单行测试文字 </div ...

  6. robots.txt文件没错,为何总提示封禁

    大家好,我的robots.txt文件没错,为何百度总提示封禁,哪位高人帮我看看原因,在此谢过. 我的站点www.haokda.com,robots.txt如下: ## robots.txt for P ...

  7. windows+caffe(五)——实例2MNIST图片

    1. 数据集 MNIST手写体数据.bmp图片:训练集60K张28*28的,测试集10K张28*28的: 训练集: 测试集: 下载地址: 2. 读取图片名称与标签,保存到trainlist.txt与t ...

  8. Thinkphp回顾(五)之前台模板中的基本语法

    一.导入CSS和JS文件 的三种方式  (了解) 1.link方式(常规) <link rel=’stylesheet’ type=’text/css’ href=’__PUBLIC__/Js/ ...

  9. wf(五)

    测试工作流: 运用wf(四)的solution: 创建单元测试项目: 1.选择HelloWorkflow解决方案,右键选择添加新建项目:选择单元测试模板,命名为HelloWorkflow.Tests. ...

  10. cf 710 E Generate a String

    题意: 开始你有数字$0$,你可以用代价$x$将该数字加$1$或减$1$(当$x > 0$时),或用代价$y$将该数字变为$2x$,那么问得到数字$n$所需的最少代价是多少. 数据范围$1 \l ...