2012-04-30 11 views
0

私はC#で作成したチェッカーゲームを接続するために必要なクライアントとサーバーアプリケーションを作成しました。私は接続するクライアントとサーバーを持っており、サーバーはラベルを更新するためにクライアントメッセージを繰り返し送信できますが、クライアントがメッセージを送信しようとするとエラーがスローされますソケットシングルクライアント/サーバー接続、サーバーは複数回送信できます。クライアントは1回のみ可能です。

"データの送受信要求は許可されませんでしたソケットが接続されておらず、(sendto呼び出しを使ってデータグラムソケットを送信しているときに)アドレスが与えられていませんでした。

ここまでは私のクライアントとサーバーです。

CLIENT -

public partial class Form1 : Form //main form that establishes connection 
{ 
    Form2 form2 = new Form2(); 
    Socket sck = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); 
    Socket acc = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); 
    IPEndPoint endPoint; 
    static byte[] Buffer { get; set; } 
    string text; 
    public Form1() 
    { 
     InitializeComponent(); 
    } 

    private void button1_Click_1(object sender, EventArgs e) 
    { 
     Thread rec = new Thread(recMsg); 
     Thread t = new Thread(ThreadProc); 
     t.Start(); //starts a form that will call the sendMsg on a button click 
     endPoint = new IPEndPoint(IPAddress.Parse("127.0.0.1"), 8887); 

     try 
     { 
      sck.Connect(endPoint); 
     } 
     catch 
     { 
      Console.WriteLine("unable to connect"); 
     } 
     rec.Start(); 
     text = textBox1.Text; 
     sendMsg(text); 
    } 
    public void sendMsg(string s) 
    { 
     //bool x = true; 
     //while (true) 
     //{ 
      //Thread.Sleep(500); 
      //if (x == true) 
      //{ 
       byte[] msgBuffer = Encoding.ASCII.GetBytes(s); 
       sck.Send(msgBuffer); //error comes here when i try to send a message from form2 says it isn't connected and has no address 
       // x = false; 
      //} 
     //} the commented out part doesn't effect how the send works it sends once and can't again, I think the problem is that the thread which establishes the connection dies but don't know how to solve. 
    } 

    public void recMsg() 
    { 
     while (true) 
     { 
      Thread.Sleep(500); 
      byte[] Buffer = new byte[255]; 
      int rec = sck.Receive(Buffer, 0, Buffer.Length, 0); 
      Array.Resize(ref Buffer, rec); 
      form2.SetText(Encoding.Default.GetString(Buffer)); 
     } 
    } 

    private void button2_Click(object sender, EventArgs e) 
    { 
     sck.Close(); 
    } 
    public void ThreadProc() 
    { 
     form2.ShowDialog(); 
    } 
} 

LABEL1、TextBox1テキストボックスとButton1を持つフォーム2、入力を取るし、Form1 SENDMSGを(呼ぶ主操作形態)

public partial class Form2 : Form 
{ 
    delegate void SetTextCallback(string text); 
    Form1 form1; 

    public Form2() 
    { 
     InitializeComponent(); 
    } 

    public void SetText(string text) 
    { 
     if (InvokeRequired) 
     { 
      SetTextCallback d = new SetTextCallback(SetText); 
      Invoke(d, new object[] { text }); 
     } 
     else 
     { 
      label1.Text = text; 
     } 
    } 

    private void button1_Click(object sender, EventArgs e) 
    { 
     form1 = new Form1(); 
     form1.sendMsg(textBox1.Text); 
    } 
} 

SERVER-

class Program 
{ 
    static Form1 form1 = new Form1(); 
    static Form2 form2 = new Form2(); 
    static byte[] buffer { get; set; } 
    static Socket sck, acc; 
    static string name; 

    static void Main(string[] args) 
    { 
     if (name == null) 
     { 
      Thread t = new Thread(ThreadProc); 
      t.Start(); 
     } 
     Thread rec = new Thread(recMsg); 
     sck = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); 
     sck.Bind(new IPEndPoint(0, 8887)); 
     Console.WriteLine("Your local IP address is: " + getIP()); 
     Console.WriteLine("Awaiting Connection"); 
     sck.Listen(0); 

     acc = sck.Accept(); 
     Console.WriteLine(" >> Accept connection from client"); 
     rec.Start(); 
     sendMsg(); 
    } 

    static string getIP() 
    { 
     string hostName = System.Net.Dns.GetHostName(); 
     IPHostEntry ipEntry = System.Net.Dns.GetHostEntry(hostName); 
     IPAddress[] addr = ipEntry.AddressList; 
     return addr[addr.Length - 1].ToString(); 
    } 

    static void recMsg() 
    { 
     while (acc.Connected) 
     { 
      Thread.Sleep(500); 
      byte[] Buffer = new byte[255]; 
      int rec = acc.Receive(Buffer, 0, Buffer.Length, 0); 
      Array.Resize(ref Buffer, rec); 
      form2.SetText(Encoding.Default.GetString(Buffer)); 
     } 
    } 

    public void btnClick(string s) 
    { 
     name = s; 
     Console.WriteLine("Name: " + name); 
     System.Threading.Thread r = new System.Threading.Thread(new System.Threading.ThreadStart(ThreadProc2)); 
     r.Start(); 
    } 
    public void sendMSG(string s) 
    { 
      try 
      { 
       buffer = Encoding.Default.GetBytes(s); 
       acc.Send(buffer); 
      } 
      catch (Exception ex) 
      { 
       Console.WriteLine(ex.ToString()); 
      } 
    } 

    static void sendMsg() 
     { 
      try 
      { 
       buffer = Encoding.Default.GetBytes(name); 
       acc.Send(buffer); 
      } 
      catch (Exception ex) 
      { 
       Console.WriteLine(ex.ToString()); 
      } 
    } 

    public static void ThreadProc() 
    { 
     form1.ShowDialog(); 
    } 

    public static void ThreadProc2() 
    { 
     form2.ShowDialog(); 
    } 
} 

Form1 - 名前を尋ねるフォームです。このフォームは、m最終的にはチェッカーゲームに必要な基本的なサーバーです。要約すると

Form2のは、基本的には、sendmsg(呼び出し、ラベル、テキストボックスとボタンがあり、私のクライアントのForm2のようなインターフェースとして使用
public partial class Form1 : Form 
{ 
    Program program; 

    public Form1() 
    { 
     InitializeComponent(); 
    } 

    private void button1_Click(object sender, EventArgs e) 
    { 
     this.Hide(); 
     program = new Program(); 
     program.btnClick(textBox1.Text); 
    } 
} 

public partial class Form2 : Form 
{ 
    delegate void SetTextCallback(string text); 
    Program program = new Program(); 

    public Form2() 
    { 
     InitializeComponent(); 
    } 

    public void SetText(string text) 
    { 
     if (InvokeRequired) 
     { 
      SetTextCallback d = new SetTextCallback(SetText); 
      this.Invoke(d, new object[] { text }); 
     } 
     else 
     { 
      this.label2.Text = text; 
     } 
    } 

    private void button1_Click(object sender, EventArgs e) 
    { 
     program.sendMSG(textBox1.Text); 
    } 
} 

、このプログラムが接続すると、サーバーができますクライアントにデータを複数回送信し、ラベルを更新します。クライアントは初めてサーバーにデータを送信し、エラーをスローします。

+0

"のC#" などを使用してタイトルを接頭辞ないでください。それがタグのためのものです。 –

答えて

0

あなたはあなたのコードは、ここから出るん実現します。

public void sendMsg(string s) 
{ 
    bool x = true; 
    while (true) 
    { 
     Thread.Sleep(500); 
     if (x == true) 
     { 
      byte[] msgBuffer = Encoding.ASCII.GetBytes(s); 
      sck.Send(msgBuffer); 
      x = false; 
     } 
    } 
} 

これは、休憩やリターンと抜け出すのは決してせずに無限ループではありません。どうすればいいですか:

public void sendMsg(string s) 
{ 
    while (true) 
    { 
     Thread.Sleep(500); 
     byte[] msgBuffer = Encoding.ASCII.GetBytes(s); 
     sck.Send(msgBuffer); 
    } 
} 
+0

無限ループの点を試してみて、死んでからの接続および文が無限回の送信からループを維持することである場合を作成したスレッドを維持することです。ボタンが押されたときに、そのメソッドがform2から呼び出されるので、おそらくそれが改訂されるはずです。 – James

+0

さて、今度はループが正確に1回送信されてから再送信されません。そのブーリアン値をインスタンス変数にし、バックグラウンドスレッドでループを開始し、ボタンがインスタンスブール値のオンとオフを切り替えるようにする必要があります。これがコーディングを主張する方法であれば。 – yamen

+0

それを許可する場合はtrue BOOLを回し、私はバックグラウンドスレッドとしてそれを実装しようとしますが、質問は問題それをしないと同じように、私はボタンをクリックしたとき、それはメソッドを呼び出しますし、それがどうなる最初の事はあるので、私はブール値を切り替える方法1回のクリックで1回 – James

3

なぜ非同期ソケットを使用しないのですか?ここにいくつかのコードがあります:

// Server socket 
class ControllerSocket : Socket, IDisposable 
{ 
    // MessageQueue queues messages to be processed by the controller 
    public Queue<MessageBase> messageQueue = null; 

    // This is a list of all attached clients 
    public List<Socket> clients = new List<Socket>(); 

    #region Events 
    // Event definitions handled in the controller 
    public delegate void SocketConnectedHandler(Socket socket); 
    public event SocketConnectedHandler SocketConnected; 

    public delegate void DataRecievedHandler(Socket socket, int bytesRead); 
    public event DataRecievedHandler DataRecieved; 

    public delegate void DataSentHandler(Socket socket, int length); 
    public event DataSentHandler DataSent; 

    public delegate void SocketDisconnectedHandler(); 
    public event SocketDisconnectedHandler SocketDisconnected; 
    #endregion 

    #region Constructor 
    public ControllerSocket(int port) 
     : base(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp) 
    { 
     // Create the message queue 
     this.messageQueue = new Queue<MessageBase>(); 

     // Acquire the host address and port, then bind the server socket 
     IPHostEntry ipHostInfo = Dns.GetHostEntry(Dns.GetHostName()); 
     IPAddress ipAddress = ipHostInfo.AddressList[0]; 
     IPEndPoint localEndPoint = new IPEndPoint(ipAddress, port); 
     this.Bind(localEndPoint); 
    } 
    #endregion 

    // Starts accepting client connections 
    public void StartListening() 
    { 
     this.Listen(100); 
     this.BeginAccept(AcceptCallback, this); 
    } 

    // Connects to a client 
    private void AcceptCallback(IAsyncResult ar) 
    { 
     Socket listener = (Socket)ar.AsyncState; 
     Socket socket = listener.EndAccept(ar); 

     try 
     { 
      // Add the connected client to the list 
      clients.Add(socket); 

      // Notify any event handlers 
      if (SocketConnected != null) 
       SocketConnected(socket); 

      // Create an initial state object to hold buffer and socket details 
      StateObject state = new StateObject(); 
      state.workSocket = socket; 
      state.BufferSize = 8192; 

      // Begin asynchronous read 
      socket.BeginReceive(state.Buffer, 0, state.BufferSize, 0, 
       ReadCallback, state); 
     } 
     catch (SocketException) 
     { 
      HandleClientDisconnect(socket); 
     } 
     finally 
     { 
      // Listen for more client connections 
      StartListening(); 
     } 
    } 

    // Read data from the client 
    private void ReadCallback(IAsyncResult ar) 
    { 
     StateObject state = (StateObject)ar.AsyncState; 
     Socket socket = state.workSocket; 

     try 
     { 
      if (socket.Connected) 
      { 
       // Read the socket 
       int bytesRead = socket.EndReceive(ar); 

       // Deserialize objects 
       foreach (MessageBase msg in MessageBase.Receive(socket, bytesRead, state)) 
       { 
        // Add objects to the message queue 
        lock (this.messageQueue) 
         messageQueue.Enqueue(msg); 
       } 

       // Notify any event handlers 
       if (DataRecieved != null) 
        DataRecieved(socket, bytesRead); 

       // Asynchronously read more client data 
       socket.BeginReceive(state.Buffer, state.readOffset, state.BufferSize - state.readOffset, 0, 
        ReadCallback, state); 
      } 
      else 
      { 
       HandleClientDisconnect(socket); 
      } 
     } 
     catch (SocketException) 
     { 
      HandleClientDisconnect(socket); 
     } 
    } 

    // Send data to a specific client 
    public void Send(Socket socket, MessageBase msg) 
    { 
     try 
     { 
      // Serialize the message 
      byte[] bytes = msg.Serialize(); 

      if (socket.Connected) 
      { 
       // Send the message 
       socket.BeginSend(bytes, 0, bytes.Length, 0, SendCallback, socket); 
      } 
      else 
      { 
       HandleClientDisconnect(socket); 
      } 
     } 
     catch (SocketException) 
     { 
      HandleClientDisconnect(socket); 
     } 
    } 

    // Broadcast data to all clients 
    public void Broadcast(MessageBase msg) 
    { 
     try 
     { 
      // Serialize the message 
      byte[] bytes = msg.Serialize(); 

      // Process all clients 
      foreach (Socket client in clients) 
      { 
       try 
       { 
        // Send the message 
        if (client.Connected) 
        { 
         client.BeginSend(bytes, 0, bytes.Length, 0, SendCallback, client); 
        } 
        else 
        { 
         HandleClientDisconnect(client); 
        } 
       } 
       catch (SocketException) 
       { 
        HandleClientDisconnect(client); 
       } 
      } 
     } 
     catch (Exception e) 
     { 
      // Serialization error 
      Console.WriteLine(e.ToString()); 
     } 
    } 

    // Data sent to a client socket 
    private void SendCallback(IAsyncResult ar) 
    { 
     try 
     { 
      Socket socket = (Socket)ar.AsyncState; 

      if (socket.Connected) 
      { 
       // Complete sending the data 
       int bytesSent = socket.EndSend(ar); 

       // Notify any attached handlers 
       if (DataSent != null) 
        DataSent(socket, bytesSent); 
      } 
      else 
      { 
       HandleClientDisconnect(socket); 
      } 
     } 
     catch (Exception e) 
     { 
      Console.WriteLine(e.ToString()); 
     } 
    } 

    private void HandleClientDisconnect(Socket client) 
    { 
     // Client socket may have shutdown unexpectedly 
     if (client.Connected) 
      client.Shutdown(SocketShutdown.Both); 

     // Close the socket and remove it from the list 
     client.Close(); 
     clients.Remove(client); 

     // Notify any event handlers 
     if (SocketDisconnected != null) 
      SocketDisconnected(); 
    } 

    // Close all client connections 
    public void Dispose() 
    { 
     foreach (Socket client in clients) 
     { 
      if (client.Connected) 
       client.Shutdown(SocketShutdown.Receive); 

      client.Close(); 
     } 
    } 
} 

// Client socket 

     class ReceiverSocket : Socket 
     { 
      // MessageQueue queues messages to be processed by the controller 
      public Queue<MessageBase> messageQueue = null; 

      #region Events 
      // Event definitions handled in the controller 
      public delegate void SocketConnectedHandler(Socket socket); 
      public event SocketConnectedHandler SocketConnected; 

      public delegate void DataRecievedHandler(Socket socket, MessageBase msg); 
      public event DataRecievedHandler DataRecieved; 

      public delegate void DataSentHandler(Socket socket, int length); 
      public event DataSentHandler DataSent; 

      public delegate void SocketDisconnectedHandler(); 
      public event SocketDisconnectedHandler SocketDisconnected; 

      private IPEndPoint remoteEP = null; 
      #endregion 

      #region Constructor 
      public ReceiverSocket(int port) 
       : base(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp) 
      { 
       // Create the message queue 
       messageQueue = new Queue<MessageBase>(); 

       // Acquire the host address and port 
       IPHostEntry ipHostInfo = Dns.GetHostEntry(Dns.GetHostName()); 
       IPAddress ipAddress = ipHostInfo.AddressList[0]; 
       remoteEP = new IPEndPoint(ipAddress, port); 
      } 
      #endregion 

      // Connect to the server 
      public void Connect() 
      { 
       this.BeginConnect(remoteEP, ConnectCallback, this); 
      } 

      // Server connected 
      private void ConnectCallback(IAsyncResult ar) 
      { 
    //   Console.WriteLine("Connect Callback"); 

       try 
       { 
        Socket client = (Socket)ar.AsyncState; 
        if (client.Connected) 
        { 
         client.EndConnect(ar); 
    //     Console.WriteLine("Connect Callback - Connected"); 

         // Create an initial state object to hold buffer and socket details 
         StateObject state = new StateObject(); 
         state.workSocket = client; 
         state.BufferSize = 8192; 

         // Notify any event handlers 
         if (SocketConnected != null) 
          SocketConnected(client); 

         // Begin asynchronous read 
         client.BeginReceive(state.Buffer, state.readOffset, state.BufferSize - state.readOffset, 0, 
          ReceiveCallback, state); 
        } 
        else 
        { 
    //     Console.WriteLine("Connect Callback - Reconnect"); 
         Thread.Sleep(5000); 
         Connect(); 
        } 
       } 
       catch (Exception ex) 
       { 
        // Attempt server reconnect 
        Reconnect(); 
       } 
      } 

      // Read data from the server 
      private void ReceiveCallback(IAsyncResult ar) 
      { 
       try 
       { 
        StateObject state = (StateObject)ar.AsyncState; 
        Socket client = state.workSocket; 

        // Read the socket 
        if (client.Connected) 
        { 
         int bytesRead = client.EndReceive(ar); 

         // Deserialize objects 
         foreach (MessageBase msg in MessageBase.Receive(client, bytesRead, state)) 
         { 
          // Add objects to the message queue 
          lock (this.messageQueue) 
           this.messageQueue.Enqueue(msg); 
         } 

         // Notify any event handlers 
         if (DataRecieved != null) 
          DataRecieved(client, null); 

         // Asynchronously read more server data 
         client.BeginReceive(state.Buffer, state.readOffset, state.BufferSize - state.readOffset, 0, 
          ReceiveCallback, state); 
        } 
        else 
        { 
         Reconnect(); 
        } 
       } 
       catch (SocketException) 
       { 
        // Attempt server reconnect 
        Reconnect(); 
       } 
      } 

      public void Send(MessageBase msg) 
      { 
       try 
       { 
        // Serialize the message 
        byte[] bytes = msg.Serialize(); 

        if (this.Connected) 
        { 
         // Send the message 
         this.BeginSend(bytes, 0, bytes.Length, 0, SendCallback, this); 
        } 
        else 
        { 
         Reconnect(); 
        } 
       } 
       catch (SocketException sox) 
       { 
        // Attempt server reconnect 
        Reconnect(); 
       } 
       catch (Exception ex) 
       { 
        int i = 0; 
       } 
      } 

      private void SendCallback(IAsyncResult ar) 
      { 
       try 
       { 
        Socket client = (Socket)ar.AsyncState; 

        if (client.Connected) 
        { 
         // Complete sending the data 
         int bytesSent = client.EndSend(ar); 

         // Notify any event handlers 
         if (DataSent != null) 
          DataSent(client, bytesSent); 
        } 
        else 
        { 
         Reconnect(); 
        } 
       } 
       catch (SocketException) 
       { 
        Reconnect(); 
       } 
      } 

      // Attempt to reconnect to the server 
      private void Reconnect() 
      { 
       try 
       { 
        // Disconnect the original socket 
        if (this.Connected) 
         this.Disconnect(true); 

        this.Close(); 

        // Notify any event handlers 
        if (SocketDisconnected != null) 
         SocketDisconnected(); 
       } 
       catch (Exception e) 
       { 
    //    Console.WriteLine(e.ToString()); 
       } 
      } 
     } 

    // Encapsulates information about the socket and data buffer 
public class StateObject 
{ 
    public Socket workSocket = null; 
    public int readOffset = 0; 
    public StringBuilder sb = new StringBuilder(); 

    private int bufferSize = 0; 
    public int BufferSize 
    { 
     set 
     { 
      this.bufferSize = value; 
      buffer = new byte[this.bufferSize]; 
     } 

     get { return this.bufferSize; } 
    } 

    private byte[] buffer = null; 
    public byte[] Buffer 
    { 
     get { return this.buffer; } 
    } 
} 

あなたがする必要があるのはあなた自身のメッセージを差し込むことです。

ソケットストリームには部分メッセージが含まれている可能性があります(ほとんどの場合)。したがって、メッセージの長さをメッセージの最初のバイトとして送信することをお勧めします。また、読み取り間に部分的なメッセージを組み立てることによって、読み取りバッファーを適切に管理する必要があります。次のメッセージ基本クラスを確認してください。

public partial class MessageBase 
{ 
    // Virtual Execute method following the Command pattern 
    public virtual string Execute(Socket socket) { return string.Empty; } 

    protected virtual bool MustEncrypt 
    { 
     get { return false; } 
    } 

    // Binary serialization 
    public byte[] Serialize() 
    { 
     using (MemoryStream stream = new MemoryStream()) 
     { 
      using (DeflateStream ds = new DeflateStream(stream, CompressionMode.Compress, true)) 
      { 
       BinaryFormatter formatter = new BinaryFormatter(); 
       formatter.Serialize(ds, this); 
       ds.Flush(); 
      } 

      byte[] bytes = stream.GetBuffer(); 
      byte[] bytes2 = new byte[stream.Length]; 
      Buffer.BlockCopy(bytes, 0, bytes2, 0, (int)stream.Length); 
//    Array.Copy(bytes, bytes2, stream.Length); 

      if (this.MustEncrypt) 
       bytes2 = RijndaelEncrptor.Instance.Encrypt(bytes2); 

      // Create a buffer large enough to hold the encrypted message and size bytes 
      byte[] data = new byte[8 + bytes2.Length]; 

      // Add the message size 
      BitConverter.GetBytes(bytes2.Length).CopyTo(data, 0); 
      BitConverter.GetBytes(this.MustEncrypt).CopyTo(data, 4); 

      // Add the message data 
      bytes2.CopyTo(data, 8); 
      return data; 
     } 
    } 

    static public MessageBase Deserialize(byte[] buffer) 
    { 
     int length = BitConverter.ToInt32(buffer, 0); 
     bool mustDecrypt = BitConverter.ToBoolean(buffer, 4); 
     MessageBase b = null; 

     try 
     { 
      b = MessageBase.Deserialize(buffer, 8, length, mustDecrypt); 
     } 
     catch { } 

     return b; 
    } 

    static public MessageBase Deserialize(byte[] buffer, int offset, int length, bool mustDecrypt) 
    { 
     // Create a buffer and initialize it with data from 
     // the input buffer offset by the specified offset amount 
     // and length determined by the specified length 
     byte[] data = new byte[length]; 
     Buffer.BlockCopy(buffer, offset, data, 0, length); 
//   Array.Copy(buffer, offset, data, 0, length); 

     // Decrypt message 
     if (mustDecrypt) 
      data = RijndaelEncrptor.Instance.Decrypt(data); 

     // Deserialize the binary data into a new object of type MessageBase 
     using (MemoryStream stream = new MemoryStream(data)) 
     { 
      using (DeflateStream ds = new DeflateStream(stream, CompressionMode.Decompress, false)) 
      { 
       BinaryFormatter formatter = new BinaryFormatter(); 
       try 
       { 
        return formatter.Deserialize(ds) as MessageBase; 
       } 
       catch 
       { 
        return null; 
       } 
      } 
     } 
    } 

    static public IEnumerable<MessageBase> Receive(Socket client, int bytesReceived, StateObject state) 
    { 
     // Total buffered count is the bytes received this read 
     // plus any unprocessed bytes from the last receive 
     int bufferLen = bytesReceived + state.readOffset; 

     // Reset the next read offset in the case 
     // this recieve lands on a message boundary 
     state.readOffset = 0; 

     // Make sure there are bytes to read 
     if (bufferLen >= 0) 
     { 
      // Initialize the current read position 
      int readOffset = 0; 

      // Process the receive buffer 
      while (readOffset < bufferLen) 
      { 
       // Get the message size 
       int length = BitConverter.ToInt32(state.Buffer, readOffset); 
       bool mustDecrypt = BitConverter.ToBoolean(state.Buffer, readOffset + 4); 

       // Increment the current read position by the length header 
       readOffset += 8; 

       // Change the buffer size if necessary 
       if (length + readOffset > state.Buffer.Length) 
       { 
        byte[] oldBuffer = new byte[state.BufferSize]; 
        Buffer.BlockCopy(state.Buffer, 0, oldBuffer, 0, state.BufferSize); 
//      Array.Copy(state.Buffer, oldBuffer, state.BufferSize); 

        state.BufferSize = length + readOffset; 
        Buffer.BlockCopy(oldBuffer, 0, state.Buffer, 0, oldBuffer.Length); 
//      Array.Copy(oldBuffer, state.Buffer, oldBuffer.Length); 
       } 

       // Ensure there are enough bytes to process the message 
       if (readOffset + length <= bufferLen) 
        yield return MessageBase.Deserialize(state.Buffer, readOffset, length, mustDecrypt); 
       else 
       { 
        // Add back the message length 
        readOffset -= 8; 

        // Reorder the receive buffer so unprocessed 
        // bytes are moved to the start of the array 
        Buffer.BlockCopy(state.Buffer, 0, state.Buffer, 0, bufferLen - readOffset); 
//      Array.Copy(state.Buffer, state.Buffer, bufferLen - readOffset); 

        // Set the receive position to the current read position 
        // This is the offset where the next socket read will start 
        state.readOffset = bufferLen - readOffset; 
        break; 
       } 

       // Update the read position by the message length 
       readOffset += length; 
      } 
     } 
    } 
} 

上記のコードはあなたに役立ちます。

+0

これらの 'Array.Copy'呼び出しがコードの一部であることを意味しましたか?そして、もう少しインデントされるべきです。また、FYI、あなたが投稿した膨大な量のコードのために、私はあなたを大いに怒らせました。しかし、それから、あなたがコードをあまりにも多く投稿して読んでいることに気づいたので、良いコードかどうかわかりません。 –

+0

多くのコードがあるかもしれませんが、それは素晴らしい作品です。インデントされたものが何を意味するのか分かりませんが、部分的なメッセージが送信される場合はArray.Copyが必要です。その場合、次の読み取りはメッセージを「完了」します。 – NickV

+0

コードをそのままコピーすることができます。私は、Server、Client、MessageLibraryの3つのプロジェクトを使用します。 MessageLibraryは他の2人の間で共有されています。 – NickV

0

私の問題を解決する方法は、おそらく標準的な方法ではないが、うまくいく。 これは、プレイヤーとプレイヤーのゲームをオンラインでやりとりするために使用することができるシンプルなチャットアプリケーションです。プログラムのクラスである

SERVER-

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

namespace testServer 
{ 
class Program 
{ 
    static Form1 form1 = new Form1(); 
    static Form2 form2 = new Form2(); 
    static byte[] buffer { get; set; } 
    static Socket sck, acc; 
    static string name; 

    public void setName(string s) 
    { 
     name = s; 
     string[] asdf = new string[2]; 
    } 

    static string getIP() 
    { 
     string hostName = System.Net.Dns.GetHostName(); 
     IPHostEntry ipEntry = System.Net.Dns.GetHostEntry(hostName); 
     IPAddress[] addr = ipEntry.AddressList; 
     return addr[addr.Length - 1].ToString(); 
    } 

    static void Main(string[] args) 
    { 
     if (name == null) 
     { 
      Thread t = new Thread(ThreadProc); 
      t.Start(); 
     } 
     sck = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); 
     sck.Bind(new IPEndPoint(0, 8888)); 
     Console.WriteLine("Your local IP address is: " + getIP()); 
     Console.WriteLine("Awaiting Connection"); 
     sck.Listen(100); 

     acc = sck.Accept(); 
     Console.WriteLine(" >> Accept connection from client"); 
     sendMsg(); 
     while (acc.Connected) 
     { 
      Thread.Sleep(500); 
      byte[] Buffer = new byte[255]; 
      int receive = acc.Receive(Buffer, 0, Buffer.Length, 0); 
      Array.Resize(ref Buffer, receive); 
      form2.SetText(Encoding.Default.GetString(Buffer)); 
     } 
    } 
    public void btnClick(string s) 
    { 
     name = s; 
     Console.WriteLine("Name: " + name); 
     System.Threading.Thread r = new System.Threading.Thread(new System.Threading.ThreadStart(ThreadProc2)); 
     r.Start(); 
    } 
    public void sendMSG(string s) 
    { 
      try 
      { 
       buffer = Encoding.Default.GetBytes(s); 
       acc.Send(buffer); 
      } 
      catch (Exception ex) 
      { 
       Console.WriteLine(ex.ToString()); 
      } 
    } 

    static void sendMsg() 
     { 
      try 
      { 
       buffer = Encoding.Default.GetBytes(name); 
       acc.Send(buffer); 
      } 
      catch (Exception ex) 
      { 
       Console.WriteLine(ex.ToString()); 
      } 
    } 
    public static void ThreadProc() 
    { 
     form1.ShowDialog(); 
    } 
    public static void ThreadProc2() 
    { 
     form2.ShowDialog(); 
    } 
} 
} 

、他の形態では、私のオリジナルのポストと同じです。

CLIENT-

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

namespace testClient100 
{ 
public partial class Form1 : Form 
{ 
    System.Net.Sockets.TcpClient clientSocket = new System.Net.Sockets.TcpClient(); 
    NetworkStream serverStream = default(NetworkStream); 
    string readData = null; 
    string ipaddress; 

    public Form1() 
    { 
     InitializeComponent(); 
    } 

    private void getMessage() 
    { 
     while (true) 
     { 
      serverStream = clientSocket.GetStream(); 
      int buffSize = 0; 
      byte[] inStream = new byte[10025]; 
      buffSize = clientSocket.ReceiveBufferSize; 
      serverStream.Read(inStream, 0, buffSize); 
      string returndata = System.Text.Encoding.ASCII.GetString(inStream); 
      readData = "" + returndata; 
      msg(); 
     } 
    } 

    private void msg() 
    { 
     if (this.InvokeRequired) 
      this.Invoke(new MethodInvoker(msg)); 
     else 
      textBox1.Text = textBox1.Text + Environment.NewLine + " >> " + readData; 
    } 

    private void button1_Click_1(object sender, EventArgs e) 
    { 
     byte[] outStream = System.Text.Encoding.ASCII.GetBytes(textBox2.Text); 
     serverStream.Write(outStream, 0, outStream.Length); 
     serverStream.Flush(); 
    } 

    private void button2_Click_1(object sender, EventArgs e) 
    { 
     ipaddress = textBox4.Text; 
     readData = "Conected to Chat Server ..."; 
     msg(); 
     clientSocket.Connect(ipaddress, 8888); 
     serverStream = clientSocket.GetStream(); 

     byte[] outStream = System.Text.Encoding.ASCII.GetBytes(textBox3.Text); 
     serverStream.Write(outStream, 0, outStream.Length); 
     serverStream.Flush(); 

     Thread ctThread = new Thread(getMessage); 
     ctThread.Start(); 
    } 

} 
} 
関連する問題