C#使用Socket实现服务器与多个客户端通信(简单的聊天系统)
扩展:
由于server端是存储了所有server与client的连接对象,因此我们是可以基于此demo的基础上实现聊天系统:
*每当一个与用户发言时,是由server接收到的某个用户的发言信息的,此时服务器端可以通过循环发送该用户发送的信息给每个已经连接连接的用户(排除发送者)。
Server端代码:
classProgram
{
//创建一个和客户端通信的套接字
staticSocketSocketWatch=null;
//定义一个集合,存储客户端信息
staticDictionaryClientConnectionItems=newDictionary{};
staticvoidMain(string[]args)
{
//端口号(用来监听的)
intport=6000;
//stringhost="127.0.0.1";
//IPAddressip=IPAddress.Parse(host);
IPAddressip=IPAddress.Any;
//将IP地址和端口号绑定到网络节点point上
IPEndPointipe=newIPEndPoint(ip,port);
//定义一个套接字用于监听客户端发来的消息,包含三个参数(IP4寻址协议,流式连接,Tcp协议)
SocketWatch=newSocket(AddressFamily.InterNetwork,SocketType.Stream,ProtocolType.Tcp);
//监听绑定的网络节点
SocketWatch.Bind(ipe);
//将套接字的监听队列长度限制为20
SocketWatch.Listen(20);
//负责监听客户端的线程:创建一个监听线程
Threadthreadwatch=newThread(WatchConnecting);
//将窗体线程设置为与后台同步,随着主线程结束而结束
threadwatch.IsBackground=true;
//启动线程
threadwatch.Start();
Console.WriteLine("开启监听......");
Console.WriteLine("点击输入任意数据回车退出程序......");
Console.ReadKey();
SocketWatch.Close();
//SocketserverSocket=null;
//inti=1;
//while(true)
//{
////receivemessage
//serverSocket=SocketWatch.Accept();
//Console.WriteLine("连接已经建立!");
//stringrecStr="";
//byte[]recByte=newbyte[4096];
//intbytes=serverSocket.Receive(recByte,recByte.Length,0);
////recStr+=Encoding.ASCII.GetString(recByte,0,bytes);
//recStr+=Encoding.GetEncoding("utf-8").GetString(recByte,0,bytes);
////sendmessage
//Console.WriteLine(recStr);
//Console.Write("请输入内容:");
//stringsendStr=Console.ReadLine();
////byte[]sendByte=Encoding.ASCII.GetBytes(sendStr);
//byte[]sendByte=Encoding.GetEncoding("utf-8").GetBytes(sendStr);
////Thread.Sleep(4000);
//serverSocket.Send(sendByte,sendByte.Length,0);
//serverSocket.Close();
//if(i>=100)
//{
//break;
//}
//i++;
//}
//sSocket.Close();
//Console.WriteLine("连接关闭!");
//Console.ReadLine();
}
//监听客户端发来的请求
staticvoidWatchConnecting()
{
Socketconnection=null;
//持续不断监听客户端发来的请求
while(true)
{
try
{
connection=SocketWatch.Accept();
}
catch(Exceptionex)
{
//提示套接字监听异常
Console.WriteLine(ex.Message);
break;
}
//客户端网络结点号
stringremoteEndPoint=connection.RemoteEndPoint.ToString();
//添加客户端信息
ClientConnectionItems.Add(remoteEndPoint,connection);
//显示与客户端连接情况
Console.WriteLine("\r\n[客户端\""+remoteEndPoint+"\"建立连接成功!客户端数量:"+ClientConnectionItems.Count+"]");
//获取客户端的IP和端口号
IPAddressclientIP=(connection.RemoteEndPointasIPEndPoint).Address;
intclientPort=(connection.RemoteEndPointasIPEndPoint).Port;
//让客户显示"连接成功的"的信息
stringsendmsg="["+"本地IP:"+clientIP+"本地端口:"+clientPort.ToString()+"连接服务端成功!]";
byte[]arrSendMsg=Encoding.UTF8.GetBytes(sendmsg);
connection.Send(arrSendMsg);
//创建一个通信线程
Threadthread=newThread(recv);
//设置为后台线程,随着主线程退出而退出
thread.IsBackground=true;
//启动线程
thread.Start(connection);
}
}
///
///接收客户端发来的信息,客户端套接字对象
///
///
staticvoidrecv(objectsocketclientpara)
{
SocketsocketServer=socketclientparaasSocket;
while(true)
{
//创建一个内存缓冲区,其大小为1024*1024字节即1M
byte[]arrServerRecMsg=newbyte[1024*1024];
//将接收到的信息存入到内存缓冲区,并返回其字节数组的长度
try
{
intlength=socketServer.Receive(arrServerRecMsg);
//将机器接受到的字节数组转换为人可以读懂的字符串
stringstrSRecMsg=Encoding.UTF8.GetString(arrServerRecMsg,0,length);
//将发送的字符串信息附加到文本框txtMsg上
Console.WriteLine("\r\n[客户端:"+socketServer.RemoteEndPoint+"时间:"+DateTime.Now.ToString("yyyy-MM-ddHH:mm:ss:fff")+"]\r\n"+strSRecMsg);
//Thread.Sleep(3000);
//socketServer.Send(Encoding.UTF8.GetBytes("["+socketServer.RemoteEndPoint+"]:"+strSRecMsg));
//发送客户端数据
if(ClientConnectionItems.Count>0)
{
foreach(varsocketTempinClientConnectionItems)
{
socketTemp.Value.Send(Encoding.UTF8.GetBytes("["+socketServer.RemoteEndPoint+"]:"+strSRecMsg));
}
}
}
catch(Exception)
{
ClientConnectionItems.Remove(socketServer.RemoteEndPoint.ToString());
//提示套接字监听异常
Console.WriteLine("\r\n[客户端\""+socketServer.RemoteEndPoint+"\"已经中断连接!客户端数量:"+ClientConnectionItems.Count+"]");
//关闭之前accept出来的和客户端进行通信的套接字
socketServer.Close();
break;
}
}
}
}
Client端代码:
classProgram
{
//创建1个客户端套接字和1个负责监听服务端请求的线程
staticThreadThreadClient=null;
staticSocketSocketClient=null;
staticvoidMain(string[]args)
{
try
{
intport=6000;
stringhost="127.0.0.1";//服务器端ip地址
IPAddressip=IPAddress.Parse(host);
IPEndPointipe=newIPEndPoint(ip,port);
//定义一个套接字监听
SocketClient=newSocket(AddressFamily.InterNetwork,SocketType.Stream,ProtocolType.Tcp);
try
{
//客户端套接字连接到网络节点上,用的是Connect
SocketClient.Connect(ipe);
}
catch(Exception)
{
Console.WriteLine("连接失败!\r\n");
Console.ReadLine();
return;
}
ThreadClient=newThread(Recv);
ThreadClient.IsBackground=true;
ThreadClient.Start();
Thread.Sleep(1000);
Console.WriteLine("请输入内容<按Enter键发送>:\r\n");
while(true)
{
stringsendStr=Console.ReadLine();
ClientSendMsg(sendStr);
}
//inti=1;
//while(true)
//{
//Console.Write("请输入内容:");
//stringsendStr=Console.ReadLine();
//SocketclientSocket=newSocket(AddressFamily.InterNetwork,SocketType.Stream,ProtocolType.Tcp);
//clientSocket.Connect(ipe);
////sendmessage
////byte[]sendBytes=Encoding.ASCII.GetBytes(sendStr);
//byte[]sendBytes=Encoding.GetEncoding("utf-8").GetBytes(sendStr);
////Thread.Sleep(4000);
//clientSocket.Send(sendBytes);
////receivemessage
//stringrecStr="";
//byte[]recBytes=newbyte[4096];
//intbytes=clientSocket.Receive(recBytes,recBytes.Length,0);
////recStr+=Encoding.ASCII.GetString(recBytes,0,bytes);
//recStr+=Encoding.GetEncoding("utf-8").GetString(recBytes,0,bytes);
//Console.WriteLine(recStr);
//clientSocket.Close();
//if(i>=100)
//{
//break;
//}
//i++;
//}
//Console.ReadLine();
//return;
//stringresult=String.Empty;
}
catch(Exceptionex)
{
Console.WriteLine(ex.Message);
Console.ReadLine();
}
}
//接收服务端发来信息的方法
publicstaticvoidRecv()
{
intx=0;
//持续监听服务端发来的消息
while(true)
{
try
{
//定义一个1M的内存缓冲区,用于临时性存储接收到的消息
byte[]arrRecvmsg=newbyte[1024*1024];
//将客户端套接字接收到的数据存入内存缓冲区,并获取长度
intlength=SocketClient.Receive(arrRecvmsg);
//将套接字获取到的字符数组转换为人可以看懂的字符串
stringstrRevMsg=Encoding.UTF8.GetString(arrRecvmsg,0,length);
if(x==1)
{
Console.WriteLine("\r\n服务器:"+DateTime.Now.ToString("yyyy-MM-ddHH:mm:ss:fff")+"\r\n"+strRevMsg+"\r\n");
}
else
{
Console.WriteLine(strRevMsg+"\r\n");
x=1;
}
}
catch(Exceptionex)
{
Console.WriteLine("远程服务器已经中断连接!"+ex.Message+"\r\n");
break;
}
}
}
//发送字符信息到服务端的方法
publicstaticvoidClientSendMsg(stringsendMsg)
{
//将输入的内容字符串转换为机器可以识别的字节数组
byte[]arrClientSendMsg=Encoding.UTF8.GetBytes(sendMsg);
//调用客户端套接字发送字节数组
SocketClient.Send(arrClientSendMsg);
}
}
测试结果:
server端:
client端:
代码下载地址:C-Socket_jb51.zip
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持毛票票。
声明:本文内容来源于网络,版权归原作者所有,内容由互联网用户自发贡献自行上传,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任。如果您发现有涉嫌版权的内容,欢迎发送邮件至:czq8825#qq.com(发邮件时,请将#更换为@)进行举报,并提供相关证据,一经查实,本站将立刻删除涉嫌侵权内容。