我想在收到回电时按钮事件 [英] I want to button event when callback received

查看:55
本文介绍了我想在收到回电时按钮事件的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在我的代码中,soket收到了异步。并且在接收回调中有发送消息。



所以回调总是循环。



收到发送收到的发送.......



在这种情况下如何我可以打断这个循环并退出。



i make quit按钮但不起作用。只有我快点击很多次。



in my code soket is received aync. and in the receive callback there is Send Message.

so callback is looped always.

received-send-received-send .......

in this situation how can i interrupted this loop and quit.

i make quit button but it doesn't work. only i click fast many times.

public class AsyncObject
{
    public Byte[] Buffer;
    public Socket WorkingSocket;
    public AsyncObject(Int32 bufferSize)
    {
        Buffer = new Byte[bufferSize];
    }
}

private Socket _mServerSocket;
private Socket _mSend;
private AsyncCallback _mFnReceiveHandler;
private AsyncCallback _mFnSendHandler;
private AsyncCallback _mFnAcceptHandler;
public void StartServer()
{
    if (_mServerSocket != null)
    {
        if (_mServerSocket.Connected)
        {
            SetText(richTextBox1, "이미 연결되어있습니다.\n");

        }
        SetText(richTextBox1, "이미 연결되어있습니다.\n");
        return;
    }

    // 비동기 작업에 사용될 대리자를 초기화합니다.
    _mFnReceiveHandler = HandleDataReceive;
    _mFnSendHandler = HandleDataSend;
    _mFnAcceptHandler = HandleClientConnectionRequest;

    // TCP 통신을 위한 소켓을 생성합니다.
    _mServerSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);

    // 특정 포트에서 모든 주소로부터 들어오는 연결을 받기 위해 포트를 바인딩합니다.
    // 사용한 포트: 8234
    _mServerSocket.Bind(new IPEndPoint(IPAddress.Parse("192.168.0.201"), 8234));
    // 연결 요청을 받기 시작합니다.
    _mServerSocket.Listen(5);

    // BeginAccept 메서드를 이용해 들어오는 연결 요청을 비동기적으로 처리합니다.
    // 연결 요청을 처리하는 함수는 handleClientConnectionRequest 입니다.
    SetText(richTextBox1, "연결중입니다.\n");
    _mServerSocket.BeginAccept(_mFnAcceptHandler, _mServerSocket);

}

public void StopServer(object sender, EventArgs e)
{
    //Thread.Sleep(1000);
    _isClose = true;
    if (_mServerSocket != null)
    {
        if (_mServerSocket.Connected || _mServerSocket.IsBound)
            _mServerSocket.Close();
        _mServerSocket = null;
    }
    if (_mSend != null)
    {
        if (_mSend.Connected)
        {
            _mSend.Disconnect(true);
            _mSend.Close();
        }
        _mSend = null;
    }

    SetText(richTextBox1, "서버가 닫혔습니다.\n");
}

public void SendMessage(String message)
{
    // 추가 정보를 넘기기 위한 변수 선언
    // 크기를 설정하는게 의미가 없습니다.
    // 왜냐하면 바로 밑의 코드에서 문자열을 유니코드 형으로 변환한 바이트 배열을 반환하기 때문에
    // 최소한의 크기르 배열을 초기화합니다.
    if(_mSend == null) return;
    if (message.Length==0) return;
    string sendmessage = message + "\n";
    var ao = new AsyncObject(1) { Buffer = Encoding.UTF8.GetBytes(sendmessage), WorkingSocket = _mSend };
    try
    {
        // 전송 시작!
        _mSend.BeginSend(ao.Buffer, 0, ao.Buffer.Length, SocketFlags.None, _mFnSendHandler, ao);
    }
    catch (SocketException secException)
    {
        MessageBox.Show(secException.ToString());
    }

}

private void HandleClientConnectionRequest(IAsyncResult ar)
{
    try
    {
        // 클라이언트의 연결 요청을 수락합니다.
        Socket sockClient = _mServerSocket.EndAccept(ar);
        _mSend = sockClient;
        // 4096 바이트의 크기를 갖는 바이트 배열을 가진 AsyncObject 클래스 생성
        var ao = new AsyncObject(4096);
        SetText(richTextBox1, sockClient.RemoteEndPoint + "의 연결 요청 수락\n");
        // 작업 중인 소켓을 저장하기 위해 sockClient 할당
        ao.WorkingSocket = sockClient;
        _isClose = false;

        // 비동기적으로 들어오는 자료를 수신하기 위해 BeginReceive 메서드 사용!
        sockClient.BeginReceive(ao.Buffer, 0, ao.Buffer.Length, SocketFlags.None, _mFnReceiveHandler, ao);
    }
    catch (ObjectDisposedException)
    {
    }
    catch (SocketException)
    {
    }
    catch (NullReferenceException)
    {
    }
}
private void HandleDataReceive(IAsyncResult ar)
{
    try
    {

        // 넘겨진 추가 정보를 가져옵니다.
        // AsyncState 속성의 자료형은 Object 형식이기 때문에 형 변환이 필요합니다~!
        var ao = (AsyncObject) ar.AsyncState;

        // 자료를 수신하고, 수신받은 바이트를 가져옵니다.
        Int32 recvBytes = ao.WorkingSocket.EndReceive(ar);
        if (!ao.WorkingSocket.Connected) return;
        // 수신받은 자료의 크기가 1 이상일 때에만 자료 처리
        if (recvBytes > 0)
        {
            SetText(richTextBox1, "메세지 받음: " + Encoding.UTF8.GetString(ao.Buffer));
            SetText(richTextBox1, "\n");
        }
        // 자료 처리가 끝났으면~
        // 이제 다시 데이터를 수신받기 위해서 수신 대기를 해야 합니다.
        // Begin~~ 메서드를 이용해 비동기적으로 작업을 대기했다면
        // 반드시 대리자 함수에서 End~~ 메서드를 이용해 비동기 작업이 끝났다고 알려줘야 합니다!
        ar.AsyncWaitHandle.WaitOne();
        Array.Clear(ao.Buffer, 0, ao.Buffer.Length);
        ao.WorkingSocket.BeginReceive(ao.Buffer, 0, ao.Buffer.Length, SocketFlags.None, _mFnReceiveHandler, ao);
        SendMessage("READ?");
    }
    catch (ObjectDisposedException)
    {
    }
    catch (SocketException)
    {
    }
}

private void HandleDataSend(IAsyncResult ar)
{

    // 넘겨진 추가 정보를 가져옵니다.
    var ao = (AsyncObject)ar.AsyncState;

    // 자료를 전송하고, 전송한 바이트를 가져옵니다.
    Int32 sentBytes = ao.WorkingSocket.EndSend(ar);

    if (sentBytes > 0)
        SetText(richTextBox1, "메세지 보냄: " + Encoding.UTF8.GetString(ao.Buffer));
}

private void Send_Click(object sender, EventArgs e)
{
    string message = richTextBox2.Text;
    SendMessage(message);
}





我的尝试:



i尝试了事件处理程序并在回调中使线程退出服务器

并且根本不起作用..

i认为事件和监听器的优先级和回调是问题。

i know listener是高优先级的下一个回调最后一个事件



What I have tried:

i tried event handler and make thread inside of callback to quit server
and it is not work at all..
i think priority of event and listener and callback is problem.
i know listener is high-priority next callback last event

推荐答案

尝试在关闭按钮中配置服务器和套接字对象。

还添加



catch(例外情况)

{

try to dispose server and socket objects in close button.
also add

catch(Exception ex)
{
MessageBox.Show(ex.Tostring);





}



//如果它引发任何其他未知异常,则捕获



}

// to catch if it throws any other unknown exceptions


这篇关于我想在收到回电时按钮事件的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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