近来的学习让我明白程序也是循序渐进的,是一个人的思想足步成熟完善的过程,实现的功能也越来越完善,自己现在缺的不仅是思想还有实现思想的理论和技术,感觉程序的学习就像愚公移山,理论技术就在那里,看你怎么去一点点的去挖走去填充自己,可怜我这把小锄头不知道要挖到什么时候 什么时候才能挖出一点深度。默默的等候这个过程吧。下面来一步步实现服务器和客户端的通信:
首先我们做一个一个服务器端和一个客户端的通信,客户端和服务器端可以相互发送和接受数据
服务器端的主要代码:
static void Main(string[] argd)
{
Console.WriteLine("server");
TcpListener server = new TcpListener(IPAddress.Parse("192.168.0.114"), 9999);//服务器端要进行监听 需要两个参数:IP地址和端口号 服务器和客户端的IP必须一致 客户端的IP要和服务器的一致 建立完连接后就不再使用 但是一直会在线程堆栈中存放着 因为while循环是个死循环 main方法不会结束
server.Start();//开始侦听传入的连接请求
//TcpClient client = server.AcceptTcpClient();//接受客户端连接 放到这里但是只能连接一次 如果想一个服务器端给多个客户端发送 则要把所有的客户端网络流放到一个集合里面
NetworkStream netstream = client.GetStream();//利用网络流读取客户端信息
Thread th = new Thread(ReadText);
th.Start(netstream);
StreamWriter swriter = new StreamWriter(netstream);//利用文件流来发送数据
while (true)
{
Console.WriteLine("---------------------------");
string con = Console.ReadLine();
swriter.WriteLine(con);
swriter.Flush();
Console.WriteLine("服务:" + DateTime.Now);
Console.WriteLine("---------------------------");
}
}
static void ReadText(object o)//接受数据
{
NetworkStream netstream = o as NetworkStream;//as的用法:as 运算符用于执行可兼容类型之间的转换。用法:expression as type
StreamReader sr = new StreamReader(netstream);
while (true)
{
Console.WriteLine("---------------------------");
string con = sr.ReadLine();
Console.WriteLine(con);
Console.WriteLine("客户:" + DateTime.Now);
Console.WriteLine("---------------------------");
}
}
}
客户端:
static void Main(string[] args)
{
Console.WriteLine("client");
TcpClient client = new TcpClient("192.168.0.10", 9999);
NetworkStream netstream = client.GetStream();
StreamWriter swriter = new StreamWriter(netstream);
Thread th = new Thread(ReadText);
th.Start(netstream);
while (true)
{
Console.WriteLine("---------------------------");
string con = Console.ReadLine();
swriter.WriteLine(con);
swriter.Flush();
Console.WriteLine("客户:" + DateTime.Now);
Console.WriteLine("---------------------------");
}
}
static void ReadText(object o)
{
NetworkStream netstream = o as NetworkStream;
StreamReader sr = new StreamReader(netstream);
while (true)
{
string con = sr.ReadLine();
Console.WriteLine("---------------------------");
Console.WriteLine(con);
Console.WriteLine("服务:" + DateTime.Now);
Console.WriteLine("---------------------------");
}
}
对程序进一步的改进,一个服务器端,多个客户端
多个客户端的通信要考虑如何存放客户端数据呢?存储多个动态数据考虑到用集合或者是哈希表 哈希表的好处是可以分别获取键和值,首先我们使用集合来存储接受的多个客户端:
服务器端:(客户端没有改变,代码如上)
namespace Server
{
class Program
{
static List<NetworkStream> tcpclients = new List<NetworkStream>();//如果想一个服务器端给多个客户端发送 则要把所有的客户端网络流放到一个集合里面
static void Main(string[] args)
{
//一个客户端接受一个服务器端
Console.WriteLine("server");
TcpListener server = new TcpListener(IPAddress.Parse("192.168.0.114"), 9999 );
server.Start();//开始侦听传入的连接请求
Thread th2 = new Thread(AcceptClient);
th2.Start(server);
while (true)
{
Console.WriteLine("开始传输数据");
Console.ReadLine();//必须有这一行 不然直接运行请选择客户端这一行了
for (int i = 0; i < tcpclients.Count; i++)//遍历客户端 并给客户端编号 按着先后运行的顺序
{
Console.WriteLine("{0}客户端", i + 1);
}
Console.WriteLine("请选择客户端:");
int re = int.Parse(Console.ReadLine()) - 1;
NetworkStream stream = tcpclients[re];//将输入的客户端存入到网络流中 并开始想给客户端写数据
StreamWriter sw = new StreamWriter(stream);//想选定的客户端传入数据
while (true)
{
Console.WriteLine("请输入要传输的内容");
Console.WriteLine("----------------------------------");
string con = Console.ReadLine();//阻塞
sw.WriteLine(con);
sw.Flush();
Console.WriteLine("服务:" + DateTime.Now);
Console.WriteLine("----------------------------------");
Console.WriteLine("退出请按E,否则请按其他键");
if (Console.ReadLine().ToUpper() == "E")
{
break;
}
}
}
}
static void ReadText(object o)
{
try
{
NetworkStream netstream = o as NetworkStream;
StreamReader sr = new StreamReader(netstream);
while (true)
{
Console.WriteLine("----------------------------------");
string con = sr.ReadLine();
Console.WriteLine(con);
Console.WriteLine("客户:" + DateTime.Now);
Console.WriteLine("----------------------------------");
}
}
catch
{
throw new Exception("服务器端断开");
}
}
/// <summary>
/// 定义一个线程来读取网络流中的数据
/// </summary>
/// <param name="o"></param>
static void AcceptClient(object o)
{
TcpListener server = o as TcpListener;
while (true)
{
TcpClient client = server.AcceptTcpClient();
NetworkStream netstream = client.GetStream();
tcpclients.Add(netstream);//将网络流加入要客户端网络流这个集合里
Thread th1 = new Thread(ReadText);//起一个线程读取客户端数据
th1.Start(netstream);
}
}
}
}
使用哈希表来存储接收的客户端
namespace Server
{
class Program
{
static Dictionary<string, NetworkStream> tcpclients = new Dictionary<string, NetworkStream>();
static void Main(string[] args)
{
Console.WriteLine("server");
TcpListener server = new TcpListener(IPAddress.Parse("192.168.0.10"), 9999);
server.Start();
Thread th = new Thread(AcceptClient);
th.Start(server);
Console.WriteLine("开始发送请按任意键!");
Console.ReadLine();
while (true)
{
foreach (string s in tcpclients.Keys)
{
Console.WriteLine(s);
}
Console.WriteLine("请选择客户端:");
string key = Console.ReadLine();
NetworkStream stream = tcpclients[key];
StreamWriter swriter = new StreamWriter(stream);
while (true)
{
Console.WriteLine("请输入发送内容:");
string con = Console.ReadLine();
swriter.WriteLine(con);
swriter.Flush();
Console.WriteLine("退出请按E,否则请按其他键");
if (Console.ReadLine().ToUpper() == "E")
{
break;
}
}
}
}
static void AcceptClient(object o)
{
TcpListener server = o as TcpListener;
while (true)
{
TcpClient clinet = server.AcceptTcpClient();
NetworkStream netstream = clinet.GetStream();
StreamReader sr = new StreamReader(netstream);
string con = sr.ReadLine();
tcpclients.Add(con, netstream);
Thread th = new Thread(ReadText);
th.Start(netstream);
}
}
static void ReadText(object o)
{
NetworkStream netstream = o as NetworkStream;
StreamReader sr = new StreamReader(netstream);
while (true)
{
Console.WriteLine("---------------------------");
string con = sr.ReadLine();
Console.WriteLine(con);
Console.WriteLine("客户:" + DateTime.Now);
Console.WriteLine("---------------------------");
}
}
}
}
进一步的实现就是利用服务器中转实现两个客户端的通信:
服务器端:获取客户端的端口号 然后接受客户端的发送的包 可以规定客户端发送格式为:发信人|收信人|内容 服务器端接收客户端的消息后进行处理 用数组的Splict方法得到 收信人 内容 然后赋给一个网络流对象 然后通过StreamWriter写入 并发送给收信人
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Net;
using System.Net.Sockets;
using System.IO;
using System.Threading;
namespace Server
{
class Program
{
static Dictionary<string, NetworkStream> tcpclients = new Dictionary<string, NetworkStream>();
static void Main(string[] args)
{
Console.WriteLine("server");
TcpListener server = new TcpListener(IPAddress.Parse("192.168.0.114"), 9999);
server.Start();
Thread th2 = new Thread(AcceptClient);
th2.Start(server);
}
static void AcceptClient(object o)
{
TcpListener server = o as TcpListener;
while (true)
{
TcpClient client = server.AcceptTcpClient();
NetworkStream netstream = client.GetStream();
StreamReader sr = new StreamReader(netstream);
string con = sr.ReadLine();
tcpclients.Add(con, netstream);
Thread th1 = new Thread(ReadText);
th1.Start(netstream);
}
}
static void ReadText(object o)
{
NetworkStream netstream = o as NetworkStream;
StreamReader sr = new StreamReader(netstream);
while (true)
{
string con= sr.ReadLine();
Console.WriteLine(con);
string[] conn= con.Split('|');
NetworkStream stream = tcpclients[conn[1]];
StreamWriter sw = new StreamWriter(stream);
sw.WriteLine(conn[0]+"|"+conn[2]);
sw.Flush();
Console.WriteLine("客户端" + DateTime.Now);
}
}
}
}
客户端:客户端发送数据以发信人|收信人|内容的格式发送
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Net;
using System.Net.Sockets;
using System.IO;
using System.Threading;
namespace Client
{
class Program
{
static void Main(string[] args)
{
Console.WriteLine("client");
TcpClient client = new TcpClient("192.168.0.114", 9999);//连接客户端
NetworkStream netstream = client.GetStream();//利用网络流写入
//客户端写
StreamWriter sw = new StreamWriter(netstream);
Console.WriteLine("请输入名称");
string con1 = Console.ReadLine();
sw.WriteLine(con1);
sw.Flush();
Thread th = new Thread(ReadText);//利用线程控制 客户端读入
th.Start(netstream);
while (true)
{
Console.WriteLine("请输入自己的发送名称:");
string con = Console.ReadLine();
Console.WriteLine("请输入接受名称:");
con += "|" + Console.ReadLine();
Console.WriteLine("请输入发送内容:");
con+= "|" + Console.ReadLine();
sw.WriteLine(con);
sw.Flush();
Console.WriteLine("客户端" + DateTime.Now);
Console.WriteLine("----------------------------------");
}
}
static void ReadText(object o)
{
NetworkStream netstream = o as NetworkStream;
StreamReader sr = new StreamReader(netstream);
while (true)
{
Console.WriteLine("----------------------------------");
string con = sr.ReadLine();
Console.WriteLine(con);
Console.WriteLine("服务器:" + DateTime.Now);
Console.WriteLine("----------------------------------");
}
}
}
}
转载于:https://blog.51cto.com/3333560/624860