2017-01-26 12 views
3

ソケットサーバー、クライアントアプリケーションを作成していますが、大きな問題があります。私の目標は、C#で非同期サーバーアプリケーションを作成し、Pythonで基本クライアントAPPを作成することです。私が単純な例に従うと、両方のプログラム作業が行われます。しかし、私がreadwriteハンドラメッセージをクライアントAPPから送信している非同期サーバを書くと、動作しません。TCP C#サーバーのPythonクライアントが通信できません

ここに私が使用しているサーバーコードの例を示します。

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

// State object for reading client data asynchronously 
public class StateObject 
{ 
// Client socket. 
public Socket workSocket = null; 
// Size of receive buffer. 
public const int BufferSize = 1024; 
// Receive buffer. 
public byte[] buffer = new byte[BufferSize]; 
// Received data string. 
public StringBuilder sb = new StringBuilder(); 
} 

public class AsynchronousSocketListener 
{ 
// Thread signal. 
public static ManualResetEvent allDone = new ManualResetEvent(false); 

public AsynchronousSocketListener() 
{ 
} 

public static void StartListening() 
{ 
    // Data buffer for incoming data. 
    byte[] bytes = new Byte[1024]; 

    // Establish the local endpoint for the socket. 
    // The DNS name of the computer 
    // running the listener is "host.contoso.com". 
    IPHostEntry ipHostInfo = Dns.Resolve(Dns.GetHostName()); 
    IPAddress ipAddress = ipHostInfo.AddressList[0]; 
    IPEndPoint localEndPoint = new IPEndPoint(ipAddress, 3333); 
    IPEndPoint ipLocal = new IPEndPoint(IPAddress.Any, 3333); 
    // Create a TCP/IP socket. 
    Socket listener = new Socket(AddressFamily.InterNetwork, 
     SocketType.Stream, ProtocolType.Tcp); 

    // Bind the socket to the local endpoint and listen for incoming connections. 
    try 
    { 
     listener.Bind(ipLocal); 
     listener.Listen(100); 

     while (true) 
     { 
      // Set the event to nonsignaled state. 
      allDone.Reset(); 

      // Start an asynchronous socket to listen for connections. 
      Console.WriteLine("Waiting for a connection..."); 
      listener.BeginAccept(
       new AsyncCallback(AcceptCallback), 
       listener); 

      // Wait until a connection is made before continuing. 
      allDone.WaitOne(); 
     } 

    } 
    catch (Exception e) 
    { 
     Console.WriteLine(e.ToString()); 
    } 

    Console.WriteLine("\nPress ENTER to continue..."); 
    Console.Read(); 

} 

public static void AcceptCallback(IAsyncResult ar) 
{ 
    // Signal the main thread to continue. 
    allDone.Set(); 

    // Get the socket that handles the client request. 
    Socket listener = (Socket)ar.AsyncState; 
    Socket handler = listener.EndAccept(ar); 

    // Create the state object. 
    StateObject state = new StateObject(); 
    state.workSocket = handler; 
    handler.BeginReceive(state.buffer, 0, StateObject.BufferSize, 0, new AsyncCallback(ReadCallback), state); 
} 

public static void ReadCallback(IAsyncResult ar) 
{ 
    String content = String.Empty; 

    // Retrieve the state object and the handler socket 
    // from the asynchronous state object. 
    StateObject state = (StateObject)ar.AsyncState; 
    Socket handler = state.workSocket; 

    // Read data from the client socket. 
    int bytesRead = handler.EndReceive(ar); 
    Console.WriteLine("\n Enters(0)"); 
    if (bytesRead > 0) 
    { 
     Console.WriteLine("\n Enters(1)"); 
     // There might be more data, so store the data received so far. 
     state.sb.Append(Encoding.ASCII.GetString(
      state.buffer, 0, bytesRead)); 

     // Check for end-of-file tag. If it is not there, read 
     // more data. 
     content = state.sb.ToString(); 
     if (content.IndexOf("<EOF>") > -1) 
     { 
      // All the data has been read from the 
      // client. Display it on the console. 
      Console.WriteLine("Read {0} bytes from socket. \n Data : {1}", 
       content.Length, content); 
      // Echo the data back to the client. 
      Send(handler, content); 
     } 
     else 
     { 
      Console.WriteLine("\n Detect"); 
      // Not all data received. Get more. 
      handler.BeginReceive(state.buffer, 0, StateObject.BufferSize, 0, 
      new AsyncCallback(ReadCallback), state); 
     } 
    } 
    Console.WriteLine("\n Enters(1)"); 

} 

private static void Send(Socket handler, String data) 
{ 
    // Convert the string data to byte data using ASCII encoding. 
    byte[] byteData = Encoding.ASCII.GetBytes(data); 

    // Begin sending the data to the remote device. 
    handler.BeginSend(byteData, 0, byteData.Length, 0, 
     new AsyncCallback(SendCallback), handler); 
} 

private static void SendCallback(IAsyncResult ar) 
{ 
    try 
    { 
     // Retrieve the socket from the state object. 
     Socket handler = (Socket)ar.AsyncState; 

     // Complete sending the data to the remote device. 
     int bytesSent = handler.EndSend(ar); 
     Console.WriteLine("Sent {0} bytes to client.", bytesSent); 

     handler.Shutdown(SocketShutdown.Both); 
     handler.Close(); 

    } 
    catch (Exception e) 
    { 
     Console.WriteLine(e.ToString()); 
    } 
} 


public static int Main(String[] args) 
{ 
    StartListening(); 
    return 0; 
} 
} 

と、ここで私は、サーバーのReadCallbackにいくつかのデバッグコードを挿入してきたように、簡単なテストクライアント

import socket 

HOST, PORT = "127.0.0.1", 3333 
data = "data" 
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) 

try: 
    sock.connect((HOST, PORT)) 
    sock.sendall(data) 
    print data 
finally: 
    sock.close() 

のためのPythonのコードですが、私はルーチンが呼び出されることがわかり、それは処理されません。受け取ったデータをメッセージとして受け取る。エンドポイントがないようです。

いずれかのアイデアや解決策があります。

答えて

0

C#の専門家ではないが、あなたにはPythonプログラムに関する問題があると思います。

try: 
    sock.connect((HOST, PORT)) 
    sock.sendall("data") 
    print data 
finally: 
    sock.close() 

あなたは定義されていないdataを印刷しようとしています。したがって、exceptの部分が実行されます(存在した場合)。次に、ソケットを閉じた状態でプログラムを終了する。

+0

そう私はちょうどポストの不一致コードを更新する必要がありますが、連続して各文字、<EOF>を検索するためにあなたがEncoding.ASCII.GetStringから取得した各文字列を解析する必要があり。 – androidgame2014

+0

'try/finally'ブロックに' except'を置くとエラーが出ますか? – Fejs

1

お客様のReadCallbackは、bytesRead == 0の場合、クライアントがデータ送信を停止したことを無視します。あなたのPythonコードが実際にを"<EOF>"なしで送信している場合は、C#サーバによって接続が忘れられてしまいます。あなたのC#コードについて


、いくつかのことは、あなたが改善する可能性があります:あなたが実際にWaitHandleを使用しない限り

  • 使用ManualResetEventSlimが、それは高速です、それは(オペレーティングシステムハンドルを使用していませんあなたはAcceptCallbackEndAcceptReadCallbackEndReceiveからの例外を処理し、おそらく例外手を向上させる必要があるプロパティ)

  • 玲はSendCallback

  • にあなたはReadCallbackStringBuilderを使用する目的に対して完全に行くたびに、あなたのStringBuilderから文字列を作成しています。

 

// Add to StateObject 
public const string EOF = "<EOF>"; 
public int eofOffset = -1; 
public int searchOffset = 0; 

// In ReadCallback 
string data = Encoding.ASCII.GetString(state.buffer, 0, bytesRead); 
state.sb.Append(data); 
int o = state.searchOffset + state.eofOffset + 1; 
while (o < state.sb.Length) 
{ 
    if (state.sb[o] != StateObject.EOF[state.eofOffset + 1]) 
    { 
     state.eofOffset = -1; 
     state.searchOffset++; 
     o = state.searchOffset; 
    } 
    else 
    { 
     state.eofOffset++; 
     if (state.eofOffset == StateObject.EOF.Length) 
     { 
      break; 
     } 
     o++; 
    } 
} 

// Replace this: 
//content = state.sb.ToString(); 
//if (content.IndexOf("<EOF>") > -1) 
// with this: 
if (state.eofOffset == StateObject.EOF.Length) 
{ 
    // Here is a good place to turn the StringBuilder into a string 
    // Perhaps truncate data to send back up to state.searchOffset 
    // ... 
} 
関連する問題