2015-10-24 2 views
1

У меня работает клиент/сервер, клиент отправляет данные на сервер без проблем, и сейчас у меня есть только RichTextBox, отображающий данные, полученные от клиента.Сервер получает сообщение от клиента, как преобразовать сообщение в нажатие клавиш в активном окне?

Что бы я хотел сделать, это показать на сервере данные, полученные в RichTextBox, а затем SendKeys сообщение в активное окно (сервер будет сведен к минимуму на системном трее, пока это происходит).

КЛИЕНТ ДОЛЯ:

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

private TcpClient client = new TcpClient(); 
    private IPEndPoint serverEndPoint = new IPEndPoint(IPAddress.Parse("MyIP"), 8888); 


public Console() 
{ 
    InitializeComponent(); 
    client.Connect(serverEndPoint); 

} 

private void SendMessage(string msg) 
{ 
    NetworkStream clientStream = client.GetStream(); 

    ASCIIEncoding encoder = new ASCIIEncoding(); 
    byte[] buffer = encoder.GetBytes(msg); 

    clientStream.Write(buffer, 0, buffer.Length); 
    clientStream.Flush(); 

} 

///... 

private void button1_Click(object sender, EventArgs e) 
{ 
    SendMessage("T"); 
} 

Теперь, все, что кажется хорошо для меня, так как мой сервер приложений получает сообщение только штрафом. Моя проблема на стороне сервера. Я не могу показаться, чтобы получить SendKeys работать, чтобы работать должным образом, так что я заметил это из фрагмента кода:

SERVER Порция:

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

private TcpListener tcpListener; 
private Thread listenThread; 
private int connectedClients = 0; 
private delegate void WriteMessageDelegate(string msg); 

public Form1() 
{ 
    InitializeComponent(); 
    Server(); 
} 

private void Server() 
{ 
    this.tcpListener = new TcpListener(IPAddress.Any, 8888); 
    this.listenThread = new Thread(new ThreadStart(ListenForClients)); 
    this.listenThread.Start(); 
} 

private void ListenForClients() 
{ 
    this.tcpListener.Start(); 

    while (true) 
    { 
     TcpClient client = this.tcpListener.AcceptTcpClient(); 


     connectedClients++; 
     lblNumberOfConnections.Text = connectedClients.ToString(); 

     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]; 
    int bytesRead; 

    while (true) 
    { 
     bytesRead = 0; 

     try 
     { 
      bytesRead = clientStream.Read(message, 0, 4096); 
     } 
     catch 
     { 
      break; 
     } 

     if (bytesRead == 0) 
     { 
      connectedClients--; 
      lblNumberOfConnections.Text = connectedClients.ToString(); 
      break; 
     } 

     ASCIIEncoding encoder = new ASCIIEncoding(); 


//Write message in RichTextBox and send keystrokes to active window 

     string msg = encoder.GetString(message, 0, bytesRead); 
     WriteMessage(msg); 
    // SendKeys.Send(msg); 

    } 

    tcpClient.Close(); 
} 

private void WriteMessage(string msg) 
{ 
    if (this.rtbServer.InvokeRequired) 
    { 
     WriteMessageDelegate d = new WriteMessageDelegate(WriteMessage); 
     this.rtbServer.Invoke(d, new object[] { msg }); 

    } 
    else 
    { 
     this.rtbServer.AppendText(msg + Environment.NewLine); 
    } 

Как я уже сказал, он отображает данные в текстовое поле просто отлично, но то, что я хотел бы сделать (и основная цель этого приложения) - принять сообщение, полученное от клиента, и добавить его в SendKeys (или аналогичный) и имитировать эти нажатия клавиш в активное окно. Я просто не могу понять, как это сделать ...

Кроме того, поскольку я использовал SendMessage в своем клиентском приложении, а некоторые из клавиш, которые мне нужно отправить в активное окно, содержат модификаторы, я просто отправил их как текстовое сообщение на мой сервер (т. е. для команды CTRL-T, я буквально отправил текст «CTRL-T» на мое серверное приложение), я надеялся, что смогу сделать что-то в этом направлении:

  • Если сообщение получен в качестве одного нажатия клавиши, просто использовать SendKeys (то есть. SendKeys.Send("T");)
  • Если сообщение получено, как нажатие клавиша с модификатором (то есть. CTRL-T) измените его на соответствующий модификатор SendKeys (то есть.)

У меня нет проблем с назначением событий для команд с модификаторами вручную, так как будут получены только две команды, которые используют модификаторы, но я не уверен, как реализовать эту часть или.

Я бы хотел, чтобы мой сервер отправил строку, полученную от моего клиента (которая, я считаю, msg), и отправьте ее в активное окно в качестве нажатия клавиши. Я хотел бы добавить в код инструкцию «IF», ​​чтобы сервер получал определенное сообщение (команды с модификаторами, которые являются всеми известными командами, поэтому я мог бы программировать, какие команды прослушивать), он отправляет указанное нажатие клавиши (в зависимости от того, какая команда была получена) в активное окно.



UPDATE:

мне удалось выяснить, как использовать SendKeys для передачи данных от клиента к активному окну на серверной машине. Это было мое первоначальное размещение команды SendKeys, которая нуждается в изменении. Я обновил его следующим образом:

//Write message in RichTextBox 

      string msg = encoder.GetString(message, 0, bytesRead); 
      WriteMessage(msg); 

     } 

     tcpClient.Close(); 
    } 

    private void WriteMessage(string msg) 
    { 
     if (this.rtbServer.InvokeRequired) 
     { 
      WriteMessageDelegate d = new WriteMessageDelegate(WriteMessage); 
      this.rtbServer.Invoke(d, new object[] { msg }); 

     } 
     else 
     { 
      this.rtbServer.AppendText(msg + Environment.NewLine); 

// SEND KEYSTROKES TO ACTIVE WINDOW 

      SendKeys.Send(msg); 
     } 

Теперь моя проблема связана с тем, что я неопытен с C#.

Я не уверен в правильности реализации инструкции IF. Мне нужно поймать строку, прежде чем отправить ее в активное окно. Мне нужно использовать оператор IF, чтобы сначала поймать строку, потому что некоторые сообщения, поступающие с сервера, не отформатированы как правильные нажатия клавиш.

В принципе, я хотел бы сделать что-нибудь, что является лишь одним символом, с помощью моего оператора IF и поискать два конкретных сообщения.

Два сообщения, которые мне нужно перехватить, это «CTRL-T» и «CTRL-H».

я не знаю правильного форматирования, так как это мой первый C# приложение, и я учусь, как я иду, но моя идея состоит в том, чтобы сообщить программе следующим образом:

Если сообщение содержится в строка «CTRL-T», то SendKeys.Send("{^T}"); Если сообщение содержится в строке является «CTRL-H», то SendKeys.Send("{^H}"); Если что-нибудь еще, то SendKeys.Send(msg);

ли это звук, как правильный способ сделать то, что я вы объяснили здесь?



EDIT: Я попытался выяснить, как отформатировать IF заявление, но это явно не так:

// SEND KEYSTROKES TO ACTIVE WINDOW 
     if (msg.Equals("CTRL-T")) 
      { 
       SendKeys.Send("{^T}"); 
      } 
      else if (msg.Equals("CTRL-H")) 
      { 
       SendKeys.Send("{^H}"); 
      } 
      else 
      { 
       SendKeys.Send(msg); 
      } 

я испытал первый IF заявление, заменив "{^T}" с "TEST", и он отправляет слово TEST в блокнот без проблем, но когда я помещаю "{^T}", как только я нажимаю кнопку для отправки этой команды, мой сервер cra Shes.

То же самое происходит и за то, чтобы отправить "{^H}"

Кто-нибудь есть идея, что я делаю неправильно здесь?

+0

обновляется для достижения большего прогресса – Patrick

+0

Итак, я понял, что мне не нужно было писать модификаторы как '" {^ T} ", все, что мне было нужно, было' '^ T" ', и это больше не сбой. По какой-то причине я не получаю желаемого эффекта в блокноте (моя тестовая среда), по какой-то причине ''^H "' выполняет «backspace» вместо того, чтобы поднимать диалоговое окно «replace». – Patrick

ответ

0

Думаю, я отвечу на свой вопрос, так как у меня есть базовая функциональность, которую я искал сейчас.

В принципе, я хотел принять сообщение из клиентского приложения и отобразить его в текстовом поле на моем серверном приложении, а затем преобразовать это сообщение в симулированные нажатия клавиш в активном окне.

Прежде чем отправлять нажатия клавиш в окно, я должен был убедиться, что только однозначные нажатия клавиш были немедленно отправлены в активное окно, а две другие известные команды, которые нуждались в модификаторах, прикрепленных к ним, были пойманы перед отправкой, и модифицировано таким образом, что они будут выступать в качестве модифицированных нажатий, а не передаются в виде фрагмента текста (то есть. «CTRL-T») вместо фактического "CTRL" button + T button

//Write message in RichTextBox 

     string msg = encoder.GetString(message, 0, bytesRead); 
     WriteMessage(msg); 

    } 

    tcpClient.Close(); 
} 

private void WriteMessage(string msg) 
{ 
    if (this.rtbServer.InvokeRequired) 
    { 
     WriteMessageDelegate d = new WriteMessageDelegate(WriteMessage); 
     this.rtbServer.Invoke(d, new object[] { msg }); 

    } 
    else 
    { 
     this.rtbServer.AppendText(msg + Environment.NewLine); 

// SEND KEYSTROKES TO ACTIVE WINDOW 

if (msg.Equals("CTRL-T")) 
     { 
      SendKeys.Send("^T"); 
     } 
     else if (msg.Equals("CTRL-H")) 
     { 
      SendKeys.Send("^H"); 
     } 
     else 
     { 
      SendKeys.Send(msg); 
     } 
Смежные вопросы