套接字编程 - 客户端服务器原理

时间:2012-12-31 14:46:52

标签: c# tcpclient

我甚至不好意思问这个问题,但是经过谷歌的疯狂搜索(开始有MSDN ......)后,我决定发布它:

刚开始学习客户端 - 服务器编程(使用C#),并尝试使用tcpClient编写我的第一个代码。我正在写服务器端和客户端。 这是我的问题:不断,客户端向服务器发送一个字符串,然后服务器将一个字符串发送回客户端,依此类推。 服务器不能连续发送2个字符串吗?他必须等待客户的回应? 这是客户端服务器的原理吗?

再一次,抱歉这个糟糕的问题。 感谢...

<> 我会尝试发布一些代码(很长一段代码......)。 我试图削减重复部分,所以希望代码有任何意义......(我用// *********标记主要的错误)

public class MServer2
{
Dictionary<String, String> nameAndPass = new Dictionary<String, String>();
Dictionary<String, List<String> > nameAndMail = new Dictionary<String, List<String>>();

public static void Main()
{
    new MServer2();
}

public MServer2()
{
    TcpListener server = new TcpListener(8500);
    try
    {
        server.Start();
        Console.WriteLine("started " + server);
        while (true)
        {
            TcpClient client = server.AcceptTcpClient();
            Console.WriteLine("connection accepted " + client);
            new Server1(client, nameAndPass, nameAndMail);
        }
    }
    catch (Exception e)
    {
        Console.WriteLine("exception" + e);
    }
    finally
    {
        server.Stop();
    }
}

class Server1
{
TcpClient client;
NetworkStream netStream;
Dictionary<String, String> nameAndPass1 = new Dictionary<String, String>();
Dictionary<String, List<String>> nameAndMail1 = new Dictionary<String, List<String>>();

internal Server1(TcpClient client, Dictionary<String, String> nameandPassFromFile, Dictionary<String, List<String> > nameAndMailsFromFile)
{
    nameAndPass1 = nameandPassFromFile;
    nameAndMail1 = nameAndMailsFromFile;

    this.client = client;
    Thread thr = new Thread(new ThreadStart(Run));
    thr.Start();
}

public void Run()
{
    try
    {
        netStream = client.GetStream();
        StreamReader reader = new StreamReader(netStream);
        StreamWriter writer = new StreamWriter(netStream);
        writer.AutoFlush = true;
        Console.WriteLine("beginning to receive loop");

        writer.WriteLine("Choose your user name.");
        strFromClient = reader.ReadLine();
        userName = strFromClient;

        writer.WriteLine("Choose your user password.");
        strFromClient = reader.ReadLine();

        password = strFromClient;

        writer.WriteLine("Do you want to see the list of email addresses? (y/n)");
        strFromClient = reader.ReadLine();

//***********************************************************************************
//HERE'S MY PROBLAM:
//HERE THE CLIENT WILL GET A STRING SHOWING HIS EMAILS, AND I WANT HIM TO GET ANOTHER     STRING ASKING "Do you want to add an email address? (y/n)", BUT IT LOOKS LIKE THE SERVER     "WAITS" FOR A RESPONSE FROM THE CLIENT TO SHOW THE NEXT STRING...
        if (strFromClient == "y")
        {   
            String tmpStr = null;
            List<String> tmp = nameAndMail1[userName];
            for(int i=0; i<nameAndMail1[userName].Count; i++)
            {
                tmpStr += tmp[i] + " ";
            }

            writer.WriteLine(tmpStr);                            
        } 
        writer.WriteLine("Do you want to add an email address? (y/n)");
        strFromClient = reader.ReadLine();

    }    

}
    catch (Exception e)
    {
        Console.WriteLine("{0} Exception caught.", e);
    }

EDIT VOL 2

OK!经过2个小时的痛苦,我想想我发现了问题,感谢菲尔弗罗斯特(天才!)---可能是在客户端... ...听到一个洞!)。

服务器连续发送2个字符串,但是我的客户端愚蠢的实现没有显示消息(从服务器返回)不遵循客户端发送的消息...

所以我再次需要你的帮助。这是我如何设计客户端表单的视图: enter image description here

我缺乏经验导致我在按下“连接到服务器”按钮时连接到服务器,并且只有在按下“发送消息”按钮时,才会显示来自服务器的消息。问题是当收到来自服务器的2条(或更多)消息而不从客户端向服务器发送消息时 - 客户端不知道收到新消息! 我想在哪里从服务器上收到消息? ('where'表示在哪个函数下,例如 - 现在它发生在sendMessage_click函数中)。

再次感谢所有帮助到目前为止!!

3 个答案:

答案 0 :(得分:6)

这个问题既不是糟糕也不是微不足道的。您正在触及协议设计中的一个重点。

AFAIK,有两种方法可以去除这只猫的皮肤:

  • “对话”(您的方式)...请求后面是回复,后面是下一个请求,依此类推。这具有易于实现的巨大优势,但是在任何时间点处理每个连接只有一个命令的最大缺点
  • “异步”(双方都可以无需等待回复即可发送)...这有执行上的困难,您需要某种请求ID才能知道哪个回复属于哪个请求:想象一下客户端发送两个请求,第一个请求的处理时间比第二个要长:答复的顺序与请求的顺序不同。

这些变体之间的选择并不总是容易的,但趋势是朝向异步模型。

异步风格中的其他困难包括确保一次只发送一条消息的机制(交织消息很可能导致不可解析的流)和超时考虑因素。

答案 1 :(得分:2)

是的,服务器可以连续发送两个字符串。但是,如果您的服务器在read()上被阻止,则可能不会。也许如果您包含有关您的计划的更多详细信息,可以提供更具体的答案。

答案 2 :(得分:1)

在TCP中,客户端到服务器和服务器到客户端通道是两个独立的流。任何一方都可以随时发送。