2009-06-18 169 views
-1

我有一个服务器和客户端应用程序在c#中使用套接字编程。在此,最大。一次可以将10个客户端连接到服务器。但我的要求是,当我通过服务器发送消息时,我必须通过IP地址阻止其中一个客户端。请帮助阻止。该方案如下..IP地址阻塞

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; 

namespace Server 
{ 
    public partial class SocketServer : Form 
    { 
     const int MAX_CLIENTS = 10; 

     public AsyncCallback pfnWorkerCallBack; 
     private Socket m_mainSocket; 
     private Socket[] m_workerSocket = new Socket[10]; 
     private int m_clientCount = 0; 
     private byte[] byData; 


     public SocketServer() 
     { 
      InitializeComponent(); 
      textBoxIP.Text = GetIP(); 
     } 

     String GetIP() 
     { 
      String strHostName = Dns.GetHostName(); 
      // Find host by name 
      IPHostEntry iphostentry = Dns.GetHostByName(strHostName); 

      // Grab the first IP addresses 
      String IPStr = ""; 
      foreach (IPAddress ipaddress in iphostentry.AddressList) 
      { 
       IPStr = ipaddress.ToString(); 
       ip = IPStr; 
       return IPStr; 
      } 
       ip = IPStr; 
       return IPStr; 

     } 



     private void Form1_Load(object sender, EventArgs e) 
     { 

     } 

     private void buttonStartListen_Click(object sender, EventArgs e) 
     { 
      try 
      { 
       // Check the port value 
       if (textBoxPort.Text == "") 
       { 
        MessageBox.Show("Please enter a Port Number"); 
        return; 
       } 
       string portStr = textBoxPort.Text; 
       int port = System.Convert.ToInt32(portStr); 
       // Create the listening socket... 
       m_mainSocket = new Socket(AddressFamily.InterNetwork, 
              SocketType.Stream, 
              ProtocolType.Tcp); 
       IPEndPoint ipLocal = new IPEndPoint(IPAddress.Any, port); 


        // Bind to local IP Address... 
        m_mainSocket.Bind(ipLocal); 
        // Start listening... 
        m_mainSocket.Listen(4); 
        // Create the call back for any client connections... 
        m_mainSocket.BeginAccept(new AsyncCallback(OnClientConnect), null); 

        UpdateControls(true); 

      } 
      catch (SocketException se) 
      { 
       MessageBox.Show(se.Message); 
      } 
     } 

     private void UpdateControls(bool listening) 
     { 
      buttonStartListen.Enabled = !listening; 
      buttonStopListen.Enabled = listening; 
     } 

     public delegate void UpdateTextCallback(string message, object obj); 

     public void OnClientConnect(IAsyncResult asyn) 
     { 
      try 
      { 
       // Here we complete/end the BeginAccept() asynchronous call 
       // by calling EndAccept() - which returns the reference to 
       // a new Socket object 
       m_workerSocket[m_clientCount] = m_mainSocket.EndAccept(asyn); 
       // Let the worker Socket do the further processing for the 
       // just connected client 
       WaitForData(m_workerSocket[m_clientCount]); 
       // Now increment the client count 
       ++m_clientCount; 
       // Display this client connection as a status message on the GUI  
       String str = String.Format("Client # {0} connected", m_clientCount); 

       //textBoxMsg.Text = str; 
       textBoxMsg.BeginInvoke(new UpdateTextCallback(UpdateText), new object[] { str, textBoxMsg }); 

       // Since the main Socket is now free, it can go back and wait for 
       // other clients who are attempting to connect 
       m_mainSocket.BeginAccept(new AsyncCallback(OnClientConnect), null); 


      } 
      catch (ObjectDisposedException) 
      { 
       System.Diagnostics.Debugger.Log(0, "1", "\n OnClientConnection: Socket has been closed\n"); 
      } 
      catch (SocketException se) 
      { 
       MessageBox.Show(se.Message); 
      } 

     } 

     private void UpdateText(string message, object ctrl) 
     { 
      if (ctrl is TextBox) 
       textBoxMsg.Text = message; 

      if(ctrl is RichTextBox) 
       richTextBoxReceivedMsg.AppendText(message); 
     } 

     public class SocketPacket 
     { 
      public System.Net.Sockets.Socket m_currentSocket; 
      public byte[] dataBuffer = new byte[1]; 
     } 

     public void WaitForData(System.Net.Sockets.Socket soc) 
     { 
      try 
      { 
       if (pfnWorkerCallBack == null) 
       { 
        // Specify the call back function which is to be 
        // invoked when there is any write activity by the 
        // connected client 
        pfnWorkerCallBack = new AsyncCallback(OnDataReceived); 
       } 
       SocketPacket theSocPkt = new SocketPacket(); 
       theSocPkt.m_currentSocket = soc; 
       // Start receiving any data written by the connected client 
       // asynchronously 
       soc.BeginReceive(theSocPkt.dataBuffer, 0, 
            theSocPkt.dataBuffer.Length, 
            SocketFlags.None, 
            pfnWorkerCallBack, 
            theSocPkt); 
      } 
      catch (SocketException se) 
      { 
       MessageBox.Show(se.Message); 
      } 

     } 

     public void OnDataReceived(IAsyncResult asyn) 
     { 
      try 
      { 
       SocketPacket socketData = (SocketPacket)asyn.AsyncState; 

       int iRx = 0; 
       // Complete the BeginReceive() asynchronous call by EndReceive() method 
       // which will return the number of characters written to the stream 
       // by the client 
       iRx = socketData.m_currentSocket.EndReceive(asyn); 
       char[] chars = new char[iRx + 1]; 
       System.Text.Decoder d = System.Text.Encoding.UTF8.GetDecoder(); 
       int charLen = d.GetChars(socketData.dataBuffer, 
             0, iRx, chars, 0); 
       System.String szData = new System.String(chars); 
       //richTextBoxReceivedMsg.AppendText(szData); 
       richTextBoxReceivedMsg.BeginInvoke(new UpdateTextCallback(UpdateText), new object[] { szData, richTextBoxReceivedMsg }); 

       // Continue the waiting for data on the Socket 
       WaitForData(socketData.m_currentSocket); 
      } 
      catch (ObjectDisposedException) 
      { 
       System.Diagnostics.Debugger.Log(0, "1", "\nOnDataReceived: Socket has been closed\n"); 
      } 
      catch (SocketException se) 
      { 
       MessageBox.Show(se.Message); 
      } 
     } 
     private void buttonStopListen_Click(object sender, EventArgs e) 
     { 
      CloseSockets(); 
      UpdateControls(false); 
     } 

     void CloseSockets() 
     { 
      if (m_mainSocket != null) 
      { 
       m_mainSocket.Close(); 
      } 
      for (int i = 0; i < m_clientCount; i++) 
      { 
       if (m_workerSocket[i] != null) 
       { 
        m_workerSocket[i].Close(); 
        m_workerSocket[i] = null; 
       } 
      } 
     } 

     private void buttonSendMsg_Click(object sender, EventArgs e) 
     { 

      try 
      { 
       Object objData = richTextBoxSendMsg.Text; 
       byData = System.Text.Encoding.ASCII.GetBytes(objData.ToString()); 
       for (int i = 0; i < m_clientCount; i++) 
       { 
        if (m_workerSocket[i] != null) 
        { 
         if (m_workerSocket[i].Connected) 
         { 

           m_workerSocket[i].Send(byData); 

         } 
        } 
       } 
      } 

      catch (SocketException se) 
      { 
       MessageBox.Show(se.Message); 
      } 
     } 

     private void Form1_Minimize(object sender, System.EventArgs e) 
     { 
      if (FormWindowState.Minimized == WindowState) 
      { 
       Hide(); 
       this.notify.Visible = true; 
      } 
     } 
     private void Form1_Resize(object sender, System.EventArgs e) 
     { 
      Show(); 
      WindowState = FormWindowState.Normal; 
      this.notify.Visible = false; 

     } 
+0

你的问题真的不清楚。请澄清你什么时候需要做什么,以及你尝试过哪些方面没有奏效。 – DarkSquid 2009-06-18 06:45:02

回答

2

这有点容易做到,你只需要看看多一点在客户端连接步骤......你想要的IP地址替换下面的127.0.0.1拒绝并抛出异常或者简单地关闭连接并返回。

public void OnClientConnect(IAsyncResult asyn) 
{ 
    try 
    { 
     TcpListener listener = (TcpListener)ar.AsyncState; 
     System.Net.Sockets.TcpClient client = listener.EndAcceptTcpClient(ar); 
     IPEndPoint clientEndPoint = (IPEndPoint)client.Client.RemoteEndPoint; 
     if (clientEndPoint.Address == new IPAddress("127.0.0.1")) 
      throw new InvalidOperationException();