2016-05-14 117 views
2

我正在使用winsock控件在C#中創建客戶端/服務器應用程序。我做了所有事情,但我堅持從客戶端發送數據到服務器的地方。在我的程序服務器上總是使用IP和端口監聽客戶端。我將數據從客戶端發送到服務器。c中的Winsock服務器/客戶端應用程序#

1)當單擊服務器窗體上的偵聽按鈕時,它將打開客戶端連接的服務器。

2)在Client form 1st中,單擊服務器連接的連接按鈕爲此消息發送消息(Connect Event:ip),我們很容易知道客戶端已連接到服務器。

3)然後我們在發送數據文本框中輸入一些數據,然後點擊發送按鈕發送數據到服務器,並保存在客戶端。

下面的代碼:

SERVER:

using System; 
using System.Collections.Generic; 
using System.Windows.Forms; 
using System.Net; 
using System.Threading; 
using System.Net.Sockets; 

namespace Server 
{ 
    public partial class Form1 : Form 
    {  
     public Form1() 
     { 
      InitializeComponent();   
     } 
     const string DEFAULT_SERVER = "ip"; 
     const int DEFAULT_PORT = 120; 

     System.Net.Sockets.Socket serverSocket; 
     System.Net.Sockets.SocketInformation serverSocketInfo; 

     public string Startup() 
     {    
      IPHostEntry hostInfo = Dns.GetHostByName(DEFAULT_SERVER); 
      IPAddress serverAddr = hostInfo.AddressList[0]; 
      var serverEndPoint = new IPEndPoint(serverAddr, DEFAULT_PORT);    
      serverSocket = new System.Net.Sockets.Socket(System.Net.Sockets.AddressFamily.InterNetwork, System.Net.Sockets.SocketType.Stream, System.Net.Sockets.ProtocolType.Tcp); 
      serverSocket.Bind(serverEndPoint); 

      return serverSocket.LocalEndPoint.ToString();  
     } 

     public string Listen() 
     { 
      int backlog = 0; 
      try 
      { 
       serverSocket.Listen(backlog); 
       return "Server listening"; 
      } 
      catch (Exception ex) 
      { 
       return "Failed to listen" + ex.ToString(); 
      } 
     } 
     public string ReceiveData() 
     { 
      System.Net.Sockets.Socket receiveSocket; 

      byte[] buffer = new byte[256]; 

      receiveSocket = serverSocket.Accept(); 

      var bytesrecd = receiveSocket.Receive(buffer); 

      receiveSocket.Close(); 

      System.Text.Encoding encoding = System.Text.Encoding.UTF8; 

      return encoding.GetString(buffer); 
     }   

     private void Listen_Click(object sender, EventArgs e) 
     { 
      string serverInfo = Startup(); 
      textBox1.Text = "Server started at:" + serverInfo; 

      serverInfo = Listen(); 
      textBox1.Text = serverInfo; 

      //string datatosend = Console.ReadLine(); 
      //SendData(datatosend); 

      serverInfo = ReceiveData(); 
      textBox1.Text = serverInfo; 

      //Console.ReadLine(); 
     } 

     private void winsock_DataArrival(object sender, AxMSWinsockLib.DMSWinsockControlEvents_DataArrivalEvent e) 
     { 
      ReceiveData(); 
      Listen(); 
     } 

     private void winsock_ConnectEvent(object sender, EventArgs e) 
     { 
      Listen(); 
     } 
    } 
} 

這一切都是完美的工作,但在這裏我的問題是,我得到的只是一個時間數據形成客戶機到服務器。當我從客戶端再次發送數據到其不工作的服務器,並給出我一些消息等

其他信息:每個套接字地址 (協議/網絡地址/端口)中的一個的使用通常允許

在服務器形式

serverSocket.Bind(serverEndPoint); 

請人幫我解決我的問題。

謝謝。

+0

你爲什麼叫receiveSocket.Close ();在ReceiveData()中?這可能是問題。 –

+0

@Mitesh Budhabhatti謝謝你的寶貴命令。我命令行//receiveSocket.Close();但是我又遇到了同樣的問題;-( – Sanjana

+0

@Sanjana - 您需要顯示客戶端代碼才能解決問題! –

回答

1

試試這個。它可以幫助你

delegate void AddTextCallback(string text); 

     public Form1() 
     { 
      InitializeComponent(); 
     } 
     private void ButtonConnected_Click(object sender, EventArgs e) 
     { 
      ThreadPool.QueueUserWorkItem(new WaitCallback(ServerHandler)); 
     } 

     private void ServerHandler(object state) 
     { 
      TcpListener _listner = new TcpListener(IPAddress.Parse("12.2.54.658"), 145); 

      _listner.Start(); 

      AddText("Server started - Listening on port 145"); 

      Socket _sock = _listner.AcceptSocket(); 

      //AddText("User from IP " + _sock.RemoteEndPoint); 

      while (_sock.Connected) 
      { 
       byte[] _Buffer = new byte[1024]; 

       int _DataReceived = _sock.Receive(_Buffer); 

       if (_DataReceived == 0) 
       { 
        break; 
       } 

       AddText("Message Received..."); 

       string _Message = Encoding.ASCII.GetString(_Buffer); 

       AddText(_Message); 
      } 

      _sock.Close(); 
      AddText("Client Disconnected."); 

      _listner.Stop(); 
      AddText("Server Stop."); 
     } 

     private void AddText(string text) 
     { 
      if (this.listBox1.InvokeRequired) 
      { 
       AddTextCallback d = new AddTextCallback(AddText); 
       this.Invoke(d, new object[] { text }); 
      } 
      else 
      { 
       this.listBox1.Items.Add(text); 
      } 
     } 

我也有同樣的問題,就像你上月,但我解決,採用這種http://stackoverflow.com/questions/21072100/receive-multiple-different-messages-tcp-listner-c-sharp從計算器。這幫助我很多希望它也有助於解決您的問題。

+0

謝謝Arthi它真的幫助我,它解決了我的問題 – Sanjana

0

我不是100%確定你理解TCP套接字,所以在這裏。

當您使用TCP偵聽器套接字時,您首先綁定到端口,以便客戶端有一個固定的已知連接點。這將爲您的套接字保留端口,直到您通過在該套接字上調用Close()來放棄它爲止。

接下來,您將聽取以開始在您所綁定的端口上接受客戶端的過程。你既可以做到這一點,也可以做到第一步,但因爲你沒有,我不在這裏。

接下來你撥打Accept()。這會阻塞(暫停執行),直到客戶端連接,然後返回專用於與該客戶端通信的套接字。如果您想允許另一個客戶端連接,則必須再次撥打Accept()

然後,您可以使用由Accept()返回的套接字與您的客戶端通信,直到完成爲止,此時您在該套接字上調用Close()

當您完成對新連接的偵聽時,您可以在偵聽器套接字上調用Close()


然而,當您按下按鈕,聆聽發生下列情況:

您綁定正確,你就開始,直到收到客戶呼叫正確地聽,然後ReceiveData()塊在接受電話。然後您會收到一些數據(雖然這是TCP,因此可能不是整個數據!),然後您立即關閉與客戶端的連接。

我認爲你得到的錯誤必須在服務器上再次按下監聽。因此,這將重新啓動整個偵聽器套接字,並且當您第二次綁定到端口時,您的上一個偵聽器仍然綁定到該端口,並因此調用失敗,因爲某個端口上已分配了某些內容。


解決方案方面,需要不斷從Accept()調用open返回的插座,直到你用它做。讓客戶端通過在其套接字上調用Shutdown()方法來處理關閉,或者建立一些標記通信結束的約定。

當您嘗試連接多個用戶時,您也會遇到麻煩,因此在某些時候您要麼需要線程或某些異步套接字,但我覺得這不在此問題的範圍之內。