none
關於SOCKET的SERVER的實作問題 RRS feed

  • 問題

  • 我目前打算在本機電腦上,執行兩個程式,一個server,一個client

    然後是用socket做連結,

    目前實作的內容是雙方都以圖形介面上,按下按鈕互傳字串,然後顯示在form上的顯示元件上,

    以下是我實作的server的程式

    而我遇到的問題是,當雙方連線後,client傳第一次訊息給server可顯示出來,但之後怎麼傳都顯示不出來

    要重新斷線再連才會再收一次訊息,

    程式如下

    using System;
    using System.Collections.Generic;
    using System.ComponentModel;
    using System.Data;
    using System.Drawing;
    using System.Text;
    using System.Windows.Forms;
    
    using System.Net.Sockets;
    using System.Net;
    using System.Threading;
    using System.Runtime.Serialization.Formatters.Binary;
    using System.IO;
    
    namespace CCDServer
    {
      public partial class Form1 : Form
      {
        delegate void SetTextCallback(byte[] data);
    	  //delegate void GetTextCallback();
    	 
        Thread startThread;
        Socket socket;
    
        public Form1()
        {
          InitializeComponent();
        }
    
        private void buttonStartListen_Click(object sender, EventArgs e)
        {
          startThread = new Thread(new ParameterizedThreadStart(start));
    	    startThread.Start();
          this.buttonStartListen.Enabled = false;
          this.buttonStopListen.Enabled = true;
        }
    
        private void start(object TransMsg)
        {
          IPEndPoint hostEP = new IPEndPoint(IPAddress.Parse("127.0.0.1"), int.Parse(this.textBoxPort.Text));
          socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
          socket.Bind(hostEP);
     
          while (true)
          {
            try
            {
              socket.Listen(50);
              Socket NewSocket = socket.Accept();
              byte[] bytesReceive = new byte[1024];
              NewSocket.Receive(bytesReceive);
              SetText(bytesReceive);
              //NewSocket.Shutdown(SocketShutdown.Both);
              //NewSocket.Close();
            }
            catch (Exception ex)
            {
              MessageBox.Show(ex.ToString());
            }
          }
        }
    
        private void SetText(byte[] data)
        {
    //richTextBoxReceivedMsg是顯示用的控制項
          if (this.richTextBoxReceivedMsg.InvokeRequired)
          {
            SetTextCallback d = new SetTextCallback(SetText);
            this.Invoke(d, new object[] { data });
          }
          else
          {
            this.richTextBoxReceivedMsg.Text = this.richTextBoxReceivedMsg.Text+Encoding.ASCII.GetString(data);
          }
        }
    
        private void buttonStopListen_Click(object sender, EventArgs e)
        {
          socket.Close();
          startThread.Abort();
          this.buttonStartListen.Enabled = true;
          this.buttonStopListen.Enabled = false;
        }
      }
    }

    我是第一次用InvokeRequired

    因此是懷疑這部份有問題,

    還請各位參考看看是那個部份要改正

    謝謝

     

     

     

    2010年6月3日 下午 12:27

解答

  • 你原來的程式

     startThread = new Thread(new ParameterizedThreadStart(start));
            startThread.Start();

    不就是開一個新的Thread去執行 private void start(object TransMsg)

    所以你應該懂得如何使用執行緒吧.

    所以從你標的位置

    byte[] bytesReceive = new byte[1024];//是從這邊要改寫嗎?
              NewSocket.Receive(bytesReceive);
              SetText(bytesReceive);

    這部份加上迴圈寫成一個Method, 然後在 private void start(object TransMsg)中去產生一個新的Thread來執行這方法就可以了. 要記得把NewSocket執行個體參考傳給Receive的Method就是了

     


    以下是簽名檔, 請勿沒事對號入座
    MSDN 文件庫很重要
    回應幫助你的人是一種禮貌, 良好的禮貌有助於激發大家對你問題回應的熱情
    進步的人會找尋自己程式中的缺點,半桶水則把自己程式的錯誤推到不相干事物的身上
    • 已提議為解答 冰糖旋風 2010年6月8日 上午 11:33
    • 已標示為解答 Lolota Lee 2010年6月10日 上午 06:51
    2010年6月4日 上午 06:04
    版主

所有回覆

  • 怎麼跟這題一樣 ? 唯一不同是你用C#, 他用VB.NET . 是老師都出一樣的作業嗎?

    http://social.msdn.microsoft.com/Forums/zh-TW/232/thread/f8d84cdf-9897-413e-b898-40da643666cf

    其實應該要在Accept後, 另外開一個Thread去做Receive和Send動作, 否則迴圈又會繞回Accept.


    以下是簽名檔, 請勿沒事對號入座
    MSDN 文件庫很重要
    回應幫助你的人是一種禮貌, 良好的禮貌有助於激發大家對你問題回應的熱情
    進步的人會找尋自己程式中的缺點,半桶水則把自己程式的錯誤推到不相干事物的身上
    2010年6月3日 下午 01:56
    版主
  • Bill Chung 先生您好

    請問你指的"另外開一個Thread去做Receive和Send動作"

    是指這個位置嗎?

    private void start(object TransMsg)
        {
          IPEndPoint hostEP = new IPEndPoint(IPAddress.Parse("127.0.0.1"), int.Parse(this.textBoxPort.Text));
          socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
          socket.Bind(hostEP);
     
          while (true)
          {
            try
            {
              socket.Listen(50);
              Socket NewSocket = socket.Accept();
              byte[] bytesReceive = new byte[1024];//是從這邊要改寫嗎?
              NewSocket.Receive(bytesReceive);
              SetText(bytesReceive);
     
            }
            catch (Exception ex)
            {
              MessageBox.Show(ex.ToString());
            }
          }
        }

    我對您說的再"開一個Thread"不是很了解,可以示範一下嗎?

    抱歉我不懂VB.NET,您提的那篇VB作法我去參考了,但我找不到他Thread的作法,(也是我VB.NET語法不大懂啦),

    不過真的是很巧啦,但我是這次工作需要用到的,不然就可以問同樣的老師了~

    再請您指導一下,謝謝

    2010年6月4日 上午 01:30
  • 你原來的程式

     startThread = new Thread(new ParameterizedThreadStart(start));
            startThread.Start();

    不就是開一個新的Thread去執行 private void start(object TransMsg)

    所以你應該懂得如何使用執行緒吧.

    所以從你標的位置

    byte[] bytesReceive = new byte[1024];//是從這邊要改寫嗎?
              NewSocket.Receive(bytesReceive);
              SetText(bytesReceive);

    這部份加上迴圈寫成一個Method, 然後在 private void start(object TransMsg)中去產生一個新的Thread來執行這方法就可以了. 要記得把NewSocket執行個體參考傳給Receive的Method就是了

     


    以下是簽名檔, 請勿沒事對號入座
    MSDN 文件庫很重要
    回應幫助你的人是一種禮貌, 良好的禮貌有助於激發大家對你問題回應的熱情
    進步的人會找尋自己程式中的缺點,半桶水則把自己程式的錯誤推到不相干事物的身上
    • 已提議為解答 冰糖旋風 2010年6月8日 上午 11:33
    • 已標示為解答 Lolota Lee 2010年6月10日 上午 06:51
    2010年6月4日 上午 06:04
    版主