客户端服务器应用程序中的问题(проблемывклиентсерверномприложении) [英] problems in a client server application(проблемы в клиент серверном приложении)

查看:62
本文介绍了客户端服务器应用程序中的问题(проблемывклиентсерверномприложении)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

一天中的好时光!

现在面临这个问题.在这种情况下,一对一聊天.

问题在于,这将始终使对方的消息来监听端口.

但这没问题,因为它不起作用
这是在单独的线程中运行的代码
(Доброговремясуток!

вотстолкнулсястакойпроблемой. пишучат1на1вданномслучае.

сутьпроблемывтомчточтобыпринятьсообщениеотдругогонужновсевремяпрослушиватьпорт.

новотнезадачаотправитьиззаэтогонеполучается
вотэтоткодзапускаетсявотдельномпотоке:)

Good time of day!

now faced with this problem. writing chat 1 on 1 in this case.

the problem is that that would take the message from the other all the time to listen to port.

but that''s no problem to send out for it does not work
Here''s the code runs in a separate thread
(Доброго время суток!

вот столкнулся с такой проблемой. пишу чат 1 на 1 в данном случае.

суть проблемы в том что что бы принять сообщение от другого нужно все время прослушивать порт.

но вот не задача отправить из за этого не получается
вот этот код запускается в отдельном потоке:)

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

using System.Net.Sockets;
using System.Net;
using System.Threading;

namespace kur_AIS_OOP_35
{
   public class SocketClient 
    {
        public static Boolean bSendMesg = true;
        public static Boolean bReadMesg = true;
        public static Boolean bExitProg = false;
        public static String ReadDATA = "000";
        public static String WriteDATA = "Вас приветствует клиент";

        IPHostEntry ipHost;
        IPAddress ipAddr;
        IPEndPoint ipEndPoint;
        Socket sender;
        string data = null;
       
        public SocketClient()
        {
            ipHost = Dns.Resolve("127.0.0.1");
            ipAddr = ipHost.AddressList[0];
            ipEndPoint = new IPEndPoint(ipAddr, 11000);
            
        }


        public static void ActionReadDATA(String data)
        {
            lock (ReadDATA)
            {
                ReadDATA = data;
            }
        }

        public void PostDataToClient()
        {
            
                byte[] msg = Encoding.UTF8.GetBytes(WriteDATA + "<theend>");
                int bytesSent = sender.Send(msg);
                bSendMesg = false;
            
        }

        public void GetDataToClient()
        {
            
            
            while (true)
            {
                //PostDataToClient();
                byte[] bytes = new byte[1024];

                int bytesRec = sender.Receive(bytes);
                if (bytesRec > 0)
                {
                    data += Encoding.UTF8.GetString(bytes, 0, bytesRec);
                }
                else
                {
                    bReadMesg = false;
                    break;
                }
                //if (data.Length < iWTF) { bReadMesg = false; break; }
                if (data.IndexOf("<theend>") > -1) //конец сообщения
                {
                    bReadMesg = false;
                    break;
                }

                if (data.IndexOf("<theendsocket>") > -1) //конец соеденения
                {
                    bExitProg = true;
                    bReadMesg = false;
                    break;
                }
               
            }
            ActionReadDATA(data);
            data = "";
        }

        public void Client() 
        {
           
         while(true)
         {
             try
             {

                 sender = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
                 sender.Connect(ipEndPoint);

                 ActionReadDATA("Сокет присоеденился к " + sender.RemoteEndPoint.ToString());
                 bReadMesg = false;

                 while (!bExitProg)//цикл для приема и передачи сообщений
                 {


                     if (bSendMesg)//посылаем
                     {

                         PostDataToClient();
                     }

                     if (bReadMesg)//принимаем
                     {
                         GetDataToClient();
                         

                     }

                 }
                 sender.Shutdown(SocketShutdown.Both);
                 sender.Close();
             }
             catch (Exception e)
             {
                 //  ActionReadDATA("Exception: " + e.ToString());
                 // bReadMesg = false; 
             }
             finally
             {
                 if (sender.Connected)
                 {
                     sender.Shutdown(SocketShutdown.Both);
                     sender.Close();
                 }
             }
         }
         } 
       } 

}
</theendsocket></theend></theend>


我该如何解决?根本不够用((((((((((((( ((какжеисправить?ужепростосилнехватает(((((((( 项目文件:
http://files.mail.ru/CG797O


how can I fix it? is simply not enough forces ((((((((((((
(как же исправить? уже просто сил не хватает((((((((((( )
project file:
http://files.mail.ru/CG797O

推荐答案

是的,您需要一直监听端口. 技巧"是:您需要聆听花费零CPU时间的方式.线程应调用一个阻塞方法,该方法将线程置于特殊的等待状态.它会被操作系统关闭,并且永远不会安排返回执行,直到客户端发出连接为止.

现在,这叫什么电话?我使用TcpListener.AcceptTcpClient().本质上,在侦听方面,您需要两个单独的线程:一个侦听传入的连接(周期性地:当一个客户端被接受时,其远程套接字被添加到您连接的客户端的容器中,然后侦听器一次又一次地侦听;另一个通过所有连接从网络流中读取/写入网络流,以便通过TCP来实现您的应用程序级别协议(在聊天的情况下,该协议非常简单,仍然是应用程序级别的协议).线程间同步原语与共享数据一起使用,共享数据是客户端的共享容器.

您将需要使用TcpClientTcpListener类.它们确实像您一样在套接字级别上工作,但是在更高的抽象级别上工作.您的演奏完全不会受到影响.

请在设计草图时查看我过去的解决方案:
来自同一端口号的多个客户端 [通过服务器触发的自动更新程序 [ http://en.wikipedia.org/wiki/Inversion_of_control [< ^ ].

为了更好地理解,请阅读有关 pull push技术服务器推送的信息:
http://en.wikipedia.org/wiki/Client%E2%80%93server_model [ ^ ],
http://en.wikipedia.org/wiki/Pull_technology [ http://en.wikipedia.org/wiki/Push_technology [
Yes, you need to listen to a port all the time. The "trick" is: you need to listen the way spending zero CPU time. The thread should call a blocking method which puts the thread in a special wait state; it is switched off by the OS and never scheduled back to execution until a connection comes from the client side.

Now, what is that kind of call? I use TcpListener.AcceptTcpClient(). Essentially, on the listening side you need two separate threads: one listening to the incoming connections (in cycle: when a client is accepted, its remote socket is added to you container of connected client, then the listener listens again, over and over; another one reads/writes from/to a network stream with all the connections so implementing your application-level protocol over TCP (in case of chat, this protocol is very simple, still am application-level protocol). You will need to use proper inter-thread synchronization primitives to work with share data, which is the shared container of clients.

You will need to use TcpClient and TcpListener classes; they do work on the level of sockets as you do, but on a bit higher level of abstraction. Your performance will not suffer at all.

Please see my past solutions where I sketch this design:
Multple clients from same port Number[^],
automatic updater triggered via server[^].

What I describe is the server side, however, you don''t have to have purely client-server architecture with single passive threads and multiple active clients. Sometimes you need inversion of control, http://en.wikipedia.org/wiki/Inversion_of_control[^].

For better understanding, please read about pull and push technology, or server push:
http://en.wikipedia.org/wiki/Client%E2%80%93server_model[^],
http://en.wikipedia.org/wiki/Pull_technology[^],
http://en.wikipedia.org/wiki/Push_technology[^].

—SA


这篇关于客户端服务器应用程序中的问题(проблемывклиентсерверномприложении)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆