这两天在学习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. 搭建S3C6410开发板的测试环境

      因为ARM架构的开发板可基于X86架构的PC在CPU指令以及二进制上都有所不同,而且如果linux驱动需要访问硬件,这些硬件很难在PC上模拟,所以就需要我们在带有这些硬件的开发板上进行调试和测试. ...

  2. Linux 常用服务总结

    使用linux有一段时间了,把自己在身边经常听到,使用linux经常遇到的linux常见服务总结出来,这样遇到问题会有更多的解决问题的办法,听别人摆这些专业术语时,才不会不知所云. 服务: 1.NFS ...

  3. 修改项目生成Gemfile的模板

    修改项目生成Gemfile的模板 gedit $rvm_path/gems/ruby-2.1.5/gems/railties-4.1.8/lib/rails/generators/rails/app/ ...

  4. android 布局学习

    各种layout用到的一些重要属性 第一类:属性值为true或false android:layout_centerHrizontal 水平居中 android:layout_centerVertic ...

  5. javaScript中定义类或对象的五种方式

    第一种方式: 工厂方法 能创建并返回特定类型的对象的工厂函数(factory function). function createCar(sColor){ var oTempCar = new Obj ...

  6. iphone 群发短信 闪退 彻底解决

    用iphone5群发短信,经常闪退,一般人多的时候,最容易出现 试了很多办法,ifile改sms.db等权限等 没有根本解决 一次操作中,发现群发时,每个号码都会显示菊花,貌似在检测什么 突然意识到, ...

  7. IIS Express 配置外部访问

    IIS Express是Visual Stuido自带的微型Web服务器,简单易用. IIS Express默认只允许本机访问,通过Visual Studio调试Web程序时,我们有时需要通过外部访问 ...

  8. Card Flip

    卡牌效果:O(∩_∩)O,只做了webkit浏览器的效果,请用chrome~ 1.首先呢,先用一个框框把卡牌包住,然后呢,搞两个子元素作为卡牌正反面.当然咯,反面是看不见滴~ <section ...

  9. Linux中环境变量文件及配置

    Linux中环境变量文件及配置   一.环境变量文件介绍 转自:http://blog.csdn.net/cscmaker/article/details/7261921 Linux中环境变量包括系统 ...

  10. 简单使用Apache POI

    Apache POI是一个纯Java编写用来操作Microsoft Office的框架,最常见的应用是让服务器后台按照特定的数据生成Excel表格提供给用户实用.前段时间因为项目的需要被大量使用,使用 ...