基于c#用Socket做一个局域网聊天工具

2019-12-30 14:18:58王冬梅

客户端代码


using System;
using System.Net;
using System.Net.Sockets;
using System.Text;
namespace tcpclient
{
  ///  <summary> 
  /// Class1 的摘要说明。
  ///  </summary> 
  class client
  {
    ///  <summary> 
    /// 应用程序的主入口点。
    ///  </summary> 
    [STAThread]
    static void Main(string[] args)
    {
      // 
      // TODO: 在此处添加代码以启动应用程序
      //
      byte[] data = new byte[1024];
      Socket newclient = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
      newclient.Bind(new IPEndPoint(IPAddress.Any, 905));
      Console.Write(" please input the server ip: ");
      string ipadd = Console.ReadLine();
      Console.WriteLine();
      Console.Write(" please input the server port: ");
      int port = Convert.ToInt32(Console.ReadLine());
      IPEndPoint ie = new IPEndPoint(IPAddress.Parse(ipadd), port); // 服务器的IP和端口
      try
      {
        // 因为客户端只是用来向特定的服务器发送信息,所以不需要绑定本机的IP和端口。不需要监听。 
        newclient.Connect(ie);
      }
      catch (SocketException e)
      {
        Console.WriteLine(" unable to connect to server ");
        Console.WriteLine(e.ToString());
        return;
      }
      int receivedDataLength = newclient.Receive(data);
      string stringdata = Encoding.ASCII.GetString(data, 0, receivedDataLength);
      Console.WriteLine(stringdata);
      while (true)
      {
        string input = Console.ReadLine();
        if (input == " exit ")
          break;
        newclient.Send(Encoding.ASCII.GetBytes(input));
        data = new byte[1024];
        receivedDataLength = newclient.Receive(data);
        stringdata = Encoding.ASCII.GetString(data, 0, receivedDataLength);
        Console.WriteLine(stringdata);
      }
      Console.WriteLine(" disconnect from sercer ");
      newclient.Shutdown(SocketShutdown.Both);
      newclient.Close();
    }
  }
}

上面的服务端和客户端都是控制台应用程序, 想办法做一个窗体类型的, 思路就是另起一个线程, 这个线程专门负责两端建立连接. 如果不采用另起线程的方法, 当等待连接而没有连接上, 或者主动连接, 服务端还没有相应时, 程序就会出现没有响应的假死状态.

当这个线程将两个端口连接成功后, 就让程序进入一个死循环, 这个死循环负责不断的接收是否有消息传来, 传来的话就在txtGetMsg中显示出来:


while (true)  // 用死循环来不断的获取信息
{
  data = new byte[1024];
  recv = newclient.Receive(data);
 
  uiContext.Send(new SendOrPostCallback(
  state =>
  {
    int txtGetMsgLength = txtGetMsg.Text.Length;
    string recMsg = "Friend:    " + System.DateTime.Now.ToString() + "n  " +Encoding.Unicode.GetString(data, 0, recv) + "n";
    txtGetMsg.AppendText(recMsg);
    txtGetMsg.Select(txtGetMsgLength, recMsg.Length - Encoding.Unicode.GetString(data, 0, recv).Length - 1);
    txtGetMsg.SelectionColor = Color.Red;
  }), null);
}