2016-05-28 99 views
0

我在問這個問題之前只是搜索一下,在C#中尋找TCP服務器和客戶端的例子。多線程TCP服務器和客戶端

我發現this鏈接,我只是使用鏈接給出的代碼,但不幸的是有一個問題,我已經放養了!

下面的代碼是用於服務器的完整代碼(控制檯)

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Text; 
using System.Net.Sockets; 

namespace TCP_Server_Console 
{ 
    class Program 
    { 
     static void Main(string[] args) 
     { 
      TcpListener serverSocket = new TcpListener(8888); 
      int requestCount = 0; 
      TcpClient clientSocket = default(TcpClient); 
      serverSocket.Start(); 
      Console.WriteLine(" >> Server Started"); 
      clientSocket = serverSocket.AcceptTcpClient(); 
      Console.WriteLine(" >> Accept connection from client"); 
      requestCount = 0; 
      while ((true)) 
      { 
       try 
       { 
        requestCount = requestCount + 1; 
        NetworkStream networkStream = clientSocket.GetStream(); 
        byte[] bytesFrom = new byte[10025]; 
        networkStream.Read(bytesFrom, 0, (int)clientSocket.ReceiveBufferSize); 
        string dataFromClient = System.Text.Encoding.ASCII.GetString(bytesFrom); 
        dataFromClient = dataFromClient.Substring(0, dataFromClient.IndexOf("$")); 
        Console.WriteLine(" >> Data from client - " + dataFromClient); 
        string serverResponse = "Last Message from client" + dataFromClient; 
        Byte[] sendBytes = Encoding.ASCII.GetBytes(serverResponse); 
        networkStream.Write(sendBytes, 0, sendBytes.Length); 
        networkStream.Flush(); 
        Console.WriteLine(" >> " + serverResponse); 
       } 
       catch (Exception ex) 
       { 
        Console.WriteLine(ex.ToString()); 
       } 
      } 
      clientSocket.Close(); 
      serverSocket.Stop(); 
      Console.WriteLine(" >> exit"); 
      Console.ReadLine(); 
     } 
    } 
} 


/*HandleClient Class */ 
using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Net.Sockets; 
using System.Text; 
using System.Threading; 
using System.Threading.Tasks; 

namespace TCP_Server_Console 
{ 
    public class HandleClient 
    { 
     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("$")); 
        Console.WriteLine(" >> " + "From client-" + clNo + dataFromClient); 
        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()); 
       } 
      } 
     } 
    } 
} 

下面的代碼是客戶端的完整代碼(Windows窗體):

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

namespace TCP_Client_Sample 
{ 
    public partial class Form1 : Form 
    { 

     System.Net.Sockets.TcpClient clientSocket = new System.Net.Sockets.TcpClient(); 
     NetworkStream serverStream; 
     public Form1() 
     { 
      InitializeComponent(); 
     } 
     private void Form1_Load(object sender, EventArgs e) 
     { 
      label_status.Text = "Client Started, Connecting..."; 
      try { 
       clientSocket.Connect("127.0.0.1", 8888); 
       if (clientSocket.Connected) 
       { 
        label_status.Text = "Connected"; 
        label_status.ForeColor = Color.Green; 
       } 
      } 
       catch (Exception xe) { 
        MessageBox.Show("OOPS!!! SERVER MUST BE STARTED FIRST! \n\n" + xe.ToString()); 
       } 

     } 

     //Function to Send Message to Server (On Button Click) 
     private void btn_send_Click(object sender, EventArgs e) 
     { 
      try { 
       NetworkStream serverStream = clientSocket.GetStream(); 
       byte[] outStream = System.Text.Encoding.ASCII.GetBytes("Message From Client$"); 
       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); 
       chatBox.AppendText(">> Server: " + returnData); 
      } 
      catch (Exception ex) { 
       MessageBox.Show("Unable to Send Data: " + ex); 
      } 
     } 
    } 
} 

每次我執行它工作並啓動的服務器的代碼。但是當我執行客戶端時,服務器給我一個異常錯誤「Specified Argument was out of the range」。

下面是完整的異常錯誤:

System.ArgumentOutOfRangeException: Specified argument was out of the range of valid values. 
Parameter name: size 
    at System.Net.Sockets.NetworkStream.Read(Byte[] buffer, Int32 offset, Int32 size) 
    at TCP_Server_Console.Program.Main(String[] args) in C:\Users\user\Documents\Visual Studio 2015\Projects\TCP_Server_Console\TCP_Server_Console\Program.cs:line 50 

我也得到同樣的錯誤每次我從客戶端窗體點擊btn_send

我在這裏的股票,我不知道是什麼問題,因爲這是我第一次與TCP套接字工作。

Anynone能幫助我嗎?

+0

對我來說,這是很多代碼。你能縮小到實際重要的東西嗎? –

+0

@UweKeim - 抱歉,儘管發佈完整代碼會更好。 – Servas

+0

您將btye數組聲明爲10025,但是接下來使用recievebuffersize讀取大量字節,它表明這些不一樣。 – BugFinder

回答

1

的問題在於,你的代碼中使用兩種不同尺寸

byte[] inStream = new byte[10025]; 
serverStream.Read(inStream, 0, (int)clientSocket.ReceiveBufferSize); 

在此。您預留了10025個字節的空間,但RecieveBufferSize可能是另一個大小,可能更大或更小,但如果更大,則會出錯。

如果您將讀取調用調用的長度與字節數組的長度相同,則不會出現問題。