2012-01-18 35 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。