2012-01-18 71 views
0

你好,我正在C#中做一個套接字程序,現在我有一個問題。我使用這個服務器程序代碼和我一直在找的這個客戶端代碼。我有一些修改它。所以我所要解決的問題是,我確實希望能夠從服務器上斷開連接,我一直在嘗試並使用Google搜索,但無法找到如何執行此操作。用這個代碼做簡單的方法是什麼?C#套接字程序

客戶端代碼

using System; 
using System.Collections.Generic; 
using System.ComponentModel; 
using System.Data; 
using System.Drawing; 
using System.Linq; 
using System.Text; 
using System.Windows.Forms; 
using System.Net.Sockets; 

namespace soket_client_delen 
{ 

public partial class Form1 : Form 
{ 
    System.Net.Sockets.TcpClient clientSocket = new System.Net.Sockets.TcpClient(); 

    public Form1() 
    { 
     InitializeComponent(); 
     this.textBox2.KeyPress += new System.Windows.Forms.KeyPressEventHandler(CheckKeys); 
    } 
    private void CheckKeys(object sender, System.Windows.Forms.KeyPressEventArgs e) 
    { 
     if (e.KeyChar == (char)13) 
     { 
      // Then Enter key was pressed 
      if (checkBox1.Checked ==true) 
       send(); 
     } 
    } 

    private void Form1_Load(object sender, EventArgs e) 
    { 
     msg("Client Started"); 
     clientSocket.Connect("127.0.0.1", 8888); 

     label1.Text = "Client Socket Program - Server Connected ..."; 
    } 


    private void button1_Click_1(object sender, EventArgs e) 
    { 
     send(); 
    } 

    public void send() 
    { 
     NetworkStream serverStream = clientSocket.GetStream(); 
     byte[] outStream = System.Text.Encoding.ASCII.GetBytes(textBox2.Text +"$"); 
     textBox2.Text = ""; 
     serverStream.Write(outStream, 0, outStream.Length); 
     serverStream.Flush(); 

     byte[] inStream = new byte[10025]; 
     serverStream.Read(inStream, 0, (int)clientSocket.ReceiveBufferSize); 
     string returndata = System.Text.Encoding.ASCII.GetString(inStream); 
     msg("Data from Server : " + returndata); 
    } 


    public void msg(string mesg) 
    { 
     textBox1.Text = textBox1.Text + Environment.NewLine + " >> " + mesg; 
    } 

    private void button2_Click(object sender, EventArgs e) 
    { 

    } 

} 
} 

和服務器代碼:

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

namespace soket_serverdelen 
{ 
class Program 
{ 
    static void Main(string[] args) 
    { 
     TcpListener serverSocket = new TcpListener(8888); 
     TcpClient clientSocket = default(TcpClient); 
     int counter = 0; 

     serverSocket.Start(); 
     Console.WriteLine(" >> " + "Server Started"); 

     counter = 0; 
     while (true) 
     { 
      counter += 1; 
      clientSocket = serverSocket.AcceptTcpClient(); 
      Console.WriteLine(" >> " + "Client No:" + Convert.ToString(counter) + " started!"); 
      handleClinet client = new handleClinet(); 
      client.startClient(clientSocket, Convert.ToString(counter)); 
     } 

     clientSocket.Close(); 
     serverSocket.Stop(); 
     Console.WriteLine(" >> " + "exit"); 
     Console.ReadLine(); 
    } 
} 

//Class to handle each client request separatly 
public class handleClinet 
{ 
    TcpClient clientSocket; 
    string clNo; 
    public void startClient(TcpClient inClientSocket, string clineNo) 
    { 
     this.clientSocket = inClientSocket; 
     this.clNo = clineNo; 
     Thread ctThread = new Thread(doChat); 
     ctThread.Start(); 
    } 
    private void doChat() 
    { 
     int requestCount = 0; 
     byte[] bytesFrom = new byte[10025]; 
     string dataFromClient = null; 
     Byte[] sendBytes = null; 
     string serverResponse = null; 
     string rCount = null; 
     requestCount = 0; 

     while ((true)) 
     { 
      try 
      { 
       requestCount = requestCount + 1; 
       NetworkStream networkStream = clientSocket.GetStream(); 
       networkStream.Read(bytesFrom, 0, (int)clientSocket.ReceiveBufferSize); 
       dataFromClient = System.Text.Encoding.ASCII.GetString(bytesFrom); 
       dataFromClient = dataFromClient.Substring(0, dataFromClient.IndexOf("$")); 

        rCount = Convert.ToString(requestCount); 
        serverResponse = "Server to clinet(" + clNo + ") " + rCount; 
        sendBytes = Encoding.ASCII.GetBytes(serverResponse); 
        networkStream.Write(sendBytes, 0, sendBytes.Length); 
        networkStream.Flush(); 
        Console.WriteLine(" >> " + serverResponse); 
      } 
      catch (Exception ex) 
      { 
       Console.WriteLine(" >> " + ex.ToString()); 
      } 
     } 
    } 
} 
} 

感謝您所有幫助

+0

不直接適用於你的問題,但是將你的套接字封裝在'using()'中或關閉並處理它們;你目前有一個內存泄漏(並且可能會發生連接泄漏)。 – 2012-01-18 16:19:58

回答

0

您需要雙方都打電話關閉。通常,雖然不是一條硬性規則,客戶端會終止連接,服務器端會對此做出響應。所以,當你的客戶端完成傳輸/接收時,客戶端就會關閉。然後服務器端對此作出響應並在其一側呼叫。

對於客戶端側:

NetworkStream ns = clientSocket.GetStream(); 
// send important stuff 
// receive important stuff from server 
ns.Close(); 

對於服務器側:

NetworkStream ns = clientSocket.GetStream(); 
int bytesRead; 
while((bytesRead = ns.Read(buffer, 0, buffer.Length)) >= 0) { 
    if(bytesRead > 0) { 
     // do really important stuff 
    } else if(bytesRead == 0) { 
     // client has trasmitted FIN packet, close and exit thread 
     ns.Close(); 
    } else { 
     // handle error condition 
     // probably close the connection 
    } 
} 

上面的代碼是唯一的模式。我沒有測試過它。你正在使用網絡流,所以這個例子(我認爲)應該是有幫助的。我通常使用select()(來自Windows API,.NET將它公開在Socket類中)。基本上,當任何一方關閉連接時,通過Close(),Windows TCP堆棧發送一個TCP FIN數據包。這表示發端希望關閉連接。另外,有人評論說你應該在using子句中使用這些流。如果你不打算直接調用Close(),這是必要的。

+0

但是,如果我想再次啓動它?那是可能的,怎麼樣?坦克 – flaimme 2012-01-19 15:36:08

+0

對不起,遲到的迴應。你想再次開始?服務器通常會循環調用Accept()(在您的原始代碼中,即AcceptTcpClient())。當接受一個新的連接時,會產生一個新的線程來處理連接,同時再次接受Accept()中的第一個塊。客戶端通過調用客戶端程序(或按下示例中的按鈕)重新啓動。 – 2012-01-24 18:36:33

0

通常,客戶端會向服務器發送註銷信號。在收到此消息後,服務器關閉連接。在退出之前,客戶端應該運行一個循環,直到serverStream.Socket.Closed = True。