C#中的多线程TcpServer工作不正常
我对C#中的多线程技术还不熟悉,我在以下在线教程中遇到过这个问题 这是我的服务器C#中的多线程TcpServer工作不正常,c#,C#,我对C#中的多线程技术还不熟悉,我在以下在线教程中遇到过这个问题 这是我的服务器 using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Net; using System.Net.Sockets; using System.Configuration; using System.Threading; namespace CoreEngine {
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Net;
using System.Net.Sockets;
using System.Configuration;
using System.Threading;
namespace CoreEngine
{
class MultithreadedTCP
{
private TcpListener myListener;
private Thread ListenThread;
public MultithreadedTCP()
{
IPAddress ip = IPAddress.Parse(ConfigurationManager.AppSettings["CoreEngineIP"]);
myListener = new TcpListener(ip, Convert.ToInt32(ConfigurationManager.AppSettings["CoreEnginePort"]));
this.ListenThread = new Thread(new ThreadStart(ListenForClients));
this.ListenThread.Start();
}
private void ListenForClients()
{
this.myListener.Start();
while (true)
{
TcpClient client = this.myListener.AcceptTcpClient();
Thread clientThread = new Thread(new ParameterizedThreadStart(HandleClientComm));
clientThread.Start(client);
}
}
private void HandleClientComm(object client)
{
TcpClient Tcpclient = (TcpClient)client;
NetworkStream clientStream = Tcpclient.GetStream();
byte[] message = new byte[4096];
while (true)
{
//send all data here
clientStream.Read(message, 0, message.Length);
Console.WriteLine("client connected : " + Encoding.UTF8.GetString(message, 0, message.Length));
//break;
}
}
}
}
这是我的客户代码。我鼓励4个客户端连接到此服务器
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Net;
using System.Net.Sockets;
using System.IO;
using System.Configuration;
using System.Configuration.Assemblies;
namespace WindowsFormsApplication1
{
class Client
{
public void send(String args)
{
TcpClient tcp = new TcpClient();
TcpClient tcp1 = new TcpClient();
TcpClient tcp2 = new TcpClient();
TcpClient tcp3 = new TcpClient();
tcp.Connect(ConfigurationManager.AppSettings["CoreEngineIP"], Convert.ToInt32(ConfigurationManager.AppSettings["CoreEnginePort"]));
tcp1.Connect(ConfigurationManager.AppSettings["CoreEngineIP"], Convert.ToInt32(ConfigurationManager.AppSettings["CoreEnginePort"]));
tcp2.Connect(ConfigurationManager.AppSettings["CoreEngineIP"], Convert.ToInt32(ConfigurationManager.AppSettings["CoreEnginePort"]));
tcp3.Connect(ConfigurationManager.AppSettings["CoreEngineIP"], Convert.ToInt32(ConfigurationManager.AppSettings["CoreEnginePort"]));
args = "client 0";
Stream str = tcp.GetStream();
ASCIIEncoding asen = new ASCIIEncoding();
byte[] b = asen.GetBytes(args);
str.Write(b, 0, b.Length);
args = "client 1";
Stream str1 = tcp1.GetStream();
ASCIIEncoding asen1 = new ASCIIEncoding();
byte[] b1 = asen.GetBytes(args);
str.Write(b1, 0, b.Length);
args = "client 2";
Stream str2 = tcp2.GetStream();
ASCIIEncoding asen2 = new ASCIIEncoding();
byte[] b2 = asen.GetBytes(args);
str.Write(b2, 0, b.Length);
args = "client 3";
Stream str3 = tcp3.GetStream();
ASCIIEncoding asen3 = new ASCIIEncoding();
byte[] b3 = asen.GetBytes(args);
str.Write(b3, 0, b.Length);
}
}
}
输出:连接的客户端:客户端0客户端1客户端2客户端3
预期产出:
已连接客户端:客户端0
已连接客户端:客户端1
已连接客户端:客户端2
客户端已连接:客户端3在每个块中调用第一个客户端的
str.Write
但是,这说明了第二个您没有考虑的问题,Read(
读取的量与写入的量不同(
连接到电线上。所有4条连接消息都合并到一个Read
)
您需要开发某种形式的“消息协议”来表示一条消息在哪里停止,另一条消息在哪里开始。最简单的方法是在发送消息之前预先设置消息的长度
客户端
args = "client 0";
Stream str = tcp.GetStream();
ASCIIEncoding asen = new ASCIIEncoding();
byte[] b = asen.GetBytes(args);
if(b.Length > 255)
throw new InvalidDataException("Messages must have a length less than 256");
str.WriteByte((byte)b.Length);
str.Write(b, 0, b.Length);
服务器端
byte[] message = new byte[256]; //This can now be 256 as that is the most messageLength can be.
while (true)
{
//get the length of the message
int messageLength = clientStream.ReadByte();
if(messageLength == -1)
break;
// "Read(" can read less than the total length you requested, so you must loop till you have the entire message.
int offset = 0;
while(offset < messageLength)
{
offset += clientStream.Read(message, offset, messageLength - offest);
}
Console.WriteLine("client connected : " + Encoding.UTF8.GetString(message, 0, message.Length));
}
byte[]message=new byte[256];//现在可以是256,因为这是最大的消息长度。
while(true)
{
//获取消息的长度
int messageLength=clientStream.ReadByte();
if(messageLength==-1)
打破
//“Read”(“Read”)可以读取的长度小于您请求的总长度,因此您必须循环,直到收到整个消息。
整数偏移=0;
while(偏移量
如果您想发送大于255字节的消息,您可以,但您需要围绕此设计协议。例如,您可以写入网络流
str.write(BitConverter.GetBytes(b.Length),0,4)
从客户端读取消息的前4个字节,然后调用int messageLength=BitConverter.ToInt32(message)
但是当您开始使用多字节数字时,您需要开始担心。(在windows桌面上总是返回true
,但在移动平台上可能会有所不同)是的,我想去,但我不能去,因为时间限制还没有到。现在去吗