这两天在学习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. C++动态加载DLL调用方法

    一.构建DLL路径 char szTmp[_MAX_PATH]; char* szPath = getcwd(szTmp, _MAX_PATH);//获取当前工作目录  //构建dll路径  strc ...

  2. 相似度分析,循环读入文件(加入了HanLP,算法第四版的库)

    相似度分析的,其中的分词可以采用HanLP即可: http://www.open-open.com/lib/view/open1421978002609.htm /****************** ...

  3. centos查看实时网络带宽占用情况方法

    Linux中查看网卡流量工具有iptraf.iftop以及nethogs等,iftop可以用来监控网卡的实时流量(可以指定网段).反向解析IP.显示端口信息等. centos安装iftop的命令如下: ...

  4. 使用geoserver发布arcgis切片

    arcgis map 版本:10.1,10.2,10.3均可 jre:7或者8 geoserver:2.8.2以上 切片:松散型,256*256  ,png 1:安装geoserver并独立部署geo ...

  5. PARENT VIEW INVALIDATE

    如果启动display list,parentview 调用invalidate,子view是不会是去调用onDraw的,因为直接调用displaylist了,如果parentview认为子view应 ...

  6. 使用tmpfs作为缓存加速缓存的文件目录

    使用tmpfs作为缓存加速缓存的文件目录 [root@web02 ~]# mount -t tmpfs tmpfs /dev/shm -o size=256m[root@web02 ~]# mount ...

  7. s3c2440 上txt 小说阅读器

    文件结构 Makefile: CROSSCOMPILE := arm-linux- CFLAGS := -Wall -O2 -c LDFLAGS := -lm -lfreetype CC := $(C ...

  8. Centos7下用命令同步标准时间

    新装的CentO7S系统服务器可能设置了错误的时间,需要调整时区和时间.如下是CentOS7系统使用NTP协议,从一个时间服务器同步标准时间: [root@localhost ~]# cp /usr/ ...

  9. animate动画jquery

    <script> $(".change").animate({height:"hide",width:"300px"},&quo ...

  10. 开发客户端软件时,出现System.Windows.Markup.XamlParseException错误

    开发客户端软件时,出现System.Windows.Markup.XamlParseException错误,通过查看错误消息,发现TCPIP的一个COM组件在安装软件过程中被删除了,重新注册了一下TC ...