Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/283.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C#客户端/服务器从服务器向客户端返回答案_C#_Tcp - Fatal编程技术网

C#客户端/服务器从服务器向客户端返回答案

C#客户端/服务器从服务器向客户端返回答案,c#,tcp,C#,Tcp,我创建了一个简单的客户机/服务器程序,它从客户机获取一个输入,并通过查看文本文件查看是否有与输入相关联的答案来返回输入的答案 我遇到的问题是,我在服务器端得到响应,但我不知道如何将其发送回客户端(它只返回客户端的输入) 第二个问题是它将执行一次,如中所示,它只接受一个输入。我尝试添加一个循环,但无法使其工作 Server.cs using System; using System.Collections.Generic; using System.IO; using System.Linq; u

我创建了一个简单的客户机/服务器程序,它从客户机获取一个输入,并通过查看文本文件查看是否有与输入相关联的答案来返回输入的答案

我遇到的问题是,我在服务器端得到响应,但我不知道如何将其发送回客户端(它只返回客户端的输入)

第二个问题是它将执行一次,如中所示,它只接受一个输入。我尝试添加一个循环,但无法使其工作

Server.cs

using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Net.Sockets;
using System.Net;

namespace server
{
    class server
    {
        const string SERVER_IP = "127.0.0.1";
        static void Main(string[] args)
        {
            //Create Dictionary
            Dictionary<string, string> dict = new Dictionary<string, string>();
            //---Read Text File containing commands ---
            StreamReader sr = new StreamReader(@"C:\Users\Desktop\potato.txt");
            string line;

            //Splits the text into commands:responses
            while ((line = sr.ReadLine()) != null)
            {
                string[] arr = line.Split(';');
                dict.Add(arr[0], arr[1]);
            }
            //Print dictionary TESTING FUNCTION
            foreach (KeyValuePair<string, string> kvp in dict)
            {
                Console.WriteLine("Command = {0} Response = {1}", kvp.Key, kvp.Value);
            }

            //---Input the port number for clients to conect---
            Console.Write("Input port" + System.Environment.NewLine);
            int PORT_NO = int.Parse(Console.ReadLine());

            //---listen at the specified IP and port no.---
            IPAddress localAdd = IPAddress.Parse(SERVER_IP);
            TcpListener listener = new TcpListener(localAdd, PORT_NO);
            Console.WriteLine("Listening for Commands");
            listener.Start();

            //---incoming client connected---
            TcpClient client = listener.AcceptTcpClient();

            //---get the incoming data through a network stream---
            NetworkStream nwStream = client.GetStream();
            byte[] buffer = new byte[client.ReceiveBufferSize];

            //---read incoming stream---
            int bytesRead = nwStream.Read(buffer, 0, client.ReceiveBufferSize);

            //---convert the command data received into a string---
            string dataReceived = Encoding.ASCII.GetString(buffer, 0, bytesRead);
            Console.WriteLine("Received Command : " + dataReceived);

            //---Search Command and send a response
            string Response;
            if (dict.TryGetValue(dataReceived, out Response))
            {
                Console.WriteLine(Response);
            }
            //---write back the response to the client---
            Console.WriteLine("Sending Response : " + Response);
            nwStream.Write(buffer, 0, bytesRead);
            Console.ReadLine();
        }
    }
}
使用系统;
使用System.Collections.Generic;
使用System.IO;
使用System.Linq;
使用系统文本;
使用System.Threading.Tasks;
使用System.Net.Sockets;
Net系统;
命名空间服务器
{
类服务器
{
const string SERVER_IP=“127.0.0.1”;
静态void Main(字符串[]参数)
{
//创建字典
Dictionary dict=新字典();
//---读取包含命令的文本文件---
StreamReader sr=新的StreamReader(@“C:\Users\Desktop\potato.txt”);
弦线;
//将文本拆分为命令:响应
而((line=sr.ReadLine())!=null)
{
字符串[]arr=line.Split(“;”);
dict.Add(arr[0],arr[1]);
}
//打印字典测试功能
foreach(dict中的KeyValuePair kvp)
{
WriteLine(“Command={0}Response={1}”,kvp.Key,kvp.Value);
}
//---输入要连接的客户端的端口号---
Console.Write(“输入端口”+System.Environment.NewLine);
int PORT_NO=int.Parse(Console.ReadLine());
//---在指定的IP和端口号上侦听---
IPAddress localAdd=IPAddress.Parse(服务器IP);
TcpListener侦听器=新的TcpListener(localAdd,端口号);
Console.WriteLine(“监听命令”);
listener.Start();
//---已连接传入客户端---
TcpClient client=listener.AcceptTcpClient();
//---通过网络流获取传入数据---
NetworkStream nwStream=client.GetStream();
byte[]buffer=新字节[client.ReceiveBufferSize];
//---读取传入流---
int bytesRead=nwStream.Read(buffer,0,client.ReceiveBufferSize);
//---将接收到的命令数据转换为字符串---
string dataReceived=Encoding.ASCII.GetString(缓冲区,0,字节读取);
Console.WriteLine(“接收到的命令:+dataReceived”);
//---搜索命令并发送响应
字符串响应;
if(dict.TryGetValue(数据接收,输出响应))
{
控制台写入线(响应);
}
//---将响应写回客户端---
Console.WriteLine(“发送响应:+响应”);
Write(缓冲区,0,字节读取);
Console.ReadLine();
}
}
}

您需要将
响应
转换为
字节[]
,就像您在发送请求的客户端中所做的那样(即
通过testosend
)。例如:

这就是说,你犯了一个典型的错误,每个人都会在没有首先读取TCP和套接字的引用的情况下编写TCP代码:你错误地认为,当你从套接字读取时,你总是会在单个操作中接收到读取的每个字节。因此,即使使用上述修复程序(它确实解决了服务器端的问题),也有可能在客户端看到部分响应(在本地测试时不太可能,但如果在Internet上或跨LAN运行,尤其是在消息大小增加时,更可能)

对于低容量的网络交互,您可能需要考虑用<代码> StreamReader < /COD>和<代码> StreamWriter < /Cord>对象包装您的<代码> NETWorkss<代码>,并使用<代码> RealLoad()/<代码>和 WraveLeIn()>代码>来接收和发送数据(即使用断线作为数据的定界符)。 至于处理多个请求,考虑到您在这里介绍的代码,最简单的方法是在

listener.Start()
方法之后围绕服务器代码添加一个循环。即,包含该语句之后的所有代码,从调用
listener.AcceptTcpClient()
开始,转到方法中的最后一条语句。然而,这同样只适用于低容量网络代码。如果您预计客户端将需要您的服务器处理多个请求,尤其是在快速连续的情况下,那么您真正想要的是客户端保持连接,即只连接一次,然后让它在同一连接上发送多个请求

类似地,如果希望能够同时处理多个客户端,则不能在单个线程中运行服务器。相反,至少您需要使用现在使用的线程阻塞逻辑,即为每个客户机创建一个新线程。更好的方法是使用非阻塞API(例如,
NetworkStream.BeginRead()
StreamReader.readlinesync()
,等等……有许多异步选项可供选择),并让.NET为您处理线程


这样做需要对服务器代码进行重大更改。您确实应该仔细查看MSDN和Stack Overflow上的各种示例,以了解这类事情是如何完成的。我也强烈建议你通读这本书。它完全不是关于.NET的,但它涵盖了有效和正确使用.NET API所需了解的所有关键细节。

nwStream.Write(缓冲区,0,字节读);-这就是为什么你要得到你发回的命令。是的,我看到了,会nw.stream.Write(Response);工作
        Console.WriteLine("Sending Response : " + Response);
        byte[] bytesToSend = ASCIIEncoding.ASCII.GetBytes(Response);
        nwStream.Write(bytesToSend, 0, bytesToSend.Length);
        Console.ReadLine();