这两天在学习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. Linux opencv安装与编译

    参考http://blog.csdn.net/solomon1558/article/details/51967280 1安装cmake以及依赖库 $ sudo apt-get install cma ...

  2. Linux启用和配置Java

    Firefox 在安装 Java 平台时,Java 插件文件将作为该安装的一部分包含在内.要在 Firefox 中使用 Java,您需要从该发行版中的插件文件手动创建符号链接指向 Firefox 预期 ...

  3. 添加群组表AppGroup和群组详细表AppGroupDetails

    添加群组表AppGroup和群组详细表AppGroupDetails CREATE TABLE [dbo].[AppGroup]( ) NOT NULL PRIMARY KEY, ) NOT NULL ...

  4. 约在CBD,吃饭

    午饭当然是外卖. CBD上班的同仁们不用约,都去了一间叫“大食堂”的餐厅. 它在商业街繁华地段的二楼,有1000平米.你不知道么,餐馆们都躲到找不着的角落,变成了厨房,这里的租金便宜得很.但它不做饭, ...

  5. newtonsoft.json 序列化,反序列化

    public class Book { public string BookID { get; set; } public DateTime PublishDate { get; set; } pub ...

  6. AppCan JSSDK模块扩展

    1.      从源码开始: 我们先看源码的8188行到9525行: window.appcan && appcan.define('window',function($,export ...

  7. Jquery remove 高级用法

    Jquery remove 高级用法 html 代码 <div class="file-image">abc1111</div><div class= ...

  8. centos7 卸载openJDK 安装jdk7

    [root@cms02 root]# rpm -qa | grep jdk java--openjdk-headless-1.7.0.75-2.5.4.2.el7_0.x86_64 java--ope ...

  9. Breeze库API总结(Spark线性代数库)(转载)

    导入 import breeze.linalg._ import breeze.numerics._ Spark Mllib底层的向量.矩阵运算使用了Breeze库,Breeze库提供了Vector/ ...

  10. git github简单知识

    Git 常用命令 git init here -- 创建本地仓库(repository),将会在文件夹下创建一个 .git 文件夹,.git 文件夹里存储了所有的版本信息.标记等内容 git remo ...