.NET之Socket编程

.NET下Socket编程,可以实现发送文件和文本,部分代码如下:

服务器端程序:

Thread threadWatch=null;//负责监听客户端连接请求的线程
Socket watchSocket=null;//服务器端负责监听的套接字

private void btnBeginListen_Click(object sender,EventArgs e)//启动服务
{
  //创建负责监听的套接字(使用IP4协议,使用流式连接,使用Tcp协议传输数据)
  watchSocket = new Socket(AddressFamily.InterNetwork,SocketType.Stream,ProtocolType.Tcp);
  //获得文本框的IP地址
  IPAddress address = IPAddress.Parse(txtIP.Text.Trim());
  //创建端口
  IPEndPoint endpoint = new IPEndPoint(address,int.Parse(txtPort.Text.Trim()));
  //绑定端口
  watchSocket.Bind(endpoint);
  //最多同时监听10个
  watchSocket.Listen(10);

  //创建负责监听的线程
  threadWatch = new Thread(WatchConnecting);
  threadWatch.IsBackgrount = true;//前台线程和后台线程。这两者的区别就是:应用程序必须运行完所有的前台线程才可以退出;而对于后台线程,应用程序则可以不考虑其是否已经运行完毕而直接退出,所有的后台线程在应用程序退出时都会自动结束。 
  threadWatch.Start();
  ShowMsg("服务器启动监听成功!");
}

//保存了服务器端所有负责和客户端通信的套接字
Dictionary<string,Socket> dict = new Dictionary<string,Socket>();
void WatchConnecting()
{
  while(true)//持续不断的监听客户端的连接请求
  {
     //创建负责通信的套接字 Accept方法是会阻塞线程的
    Socket SokConnection = watchSocket.Accept();
    //将监听到的客户端的远程终结点添加到ListBox控件中
    lbOnLint.Items.Add(SokConnection.RemoteEndPoint.ToString());
    //将客户端的远程终结点和通信套接字以键值对的方式添加到dict中
    dict.Add(SokConnection.RemoteEndPoint.Tostring(),SokConnection);

   //负责接收的线程
   Thread thr = new Thread(RecMsg);
   thr.IsBackground = true;
   thr.Start(SokConnection);
   ShowMsg("客户端连接成功!"+SokConnection.RemoteEndPoint.ToString());
  }
}

//服务器监听客户端发来的消息
void RecMsg(object socketClientpara)
{
  Socket soketClient = socketClientpara as Socket;
  while(true)
  {
    byte[] arrMsgRec = new byte[1024*1024*2];//2M
    int length = -1;
    try
    {
      length = socketClient.Receive(arrMsgRec);
    }
    catch(SocketException ex)
    {
      ShowMsg("异常:"+ex.Message);
      dict.Remove(socketClient.RemoteEndPoint.ToString());
      lbOnLine.Items.Remove(soketClient.ReomteEndPoint.ToString());
      return;
    }
    catch(Exception ex)
    {
      ShowMsg("异常:"+ex.Message);
      return;
    }
    if(arrMsgRec[0] == 0)//0代表文本文字数据
    {
      string strMsgRec = System.Text.Encoding.UTF8.GetString(arrMsgRec,1,length-1);
      ShowMsg("收到:"+strMsgRec);
    }
    else if(arrMsgRec[0] == 1)//1代表文件数据(视频、图片等)
    {
      SaveFileDialog sfd = new SaveFileDialog();
      if(sfd.ShowDialog() == System.Windows.Forms.DialogResult.OK)
      {
        string fileSavePath = sfd.FileName;
        using(FileStream fs = new FileStream(fileSavePath,FileMode.Create))
        {
          fs.Write(arrMsgRec,1,length-1);
          SHowMsg("文件保存成功"+fileSavePath);
        }
      }
    }
  }
}

void ShowMsg(string msg)
{
  txtMsg.AppendText(msg+"\r\n");//这里禁止了跨线程的检测,实际项目中不要这么做
}


//发送给好友
private void btnSend_Click(object sender,EventArgs e)
{
  if(string.IsNullOrEmpty(lbOnLine.Text))
  {
    MessageBox.Show("请选择要发送的好友");
  }
  else
  {
    string strMsg = txtMsgSend.Text.Trim();
    byte[] arrMsg = System.Text.Encoding.UTF8.GetBytes(strMsg);
    string strClientKey = lbOnLine.Text;
    try
    {
      dict[StrClientKey].Send(arrMsg);
      ShowMsg("发送:",strMsg);
    }
    catch(SocketException ex)
    {
      ShowMsg("异常:"+ex.Message);
    }
    catch(Exception ex)
    {
      ShowMsg("异常:"+ex.Message);
    }
  }
}

//群发
private void btnSendAll_Click(object sender,EventArgs e)
{
  string strMsg = txtMsgSend.Text.Trim();
  byte[] arrMsg = System.Text.Encoding.UTF8.GetBytes(strMsg);
  foreach(Socket s in dict.Values)
  {
    s.Send(arrMsg);
  }
  ShowMsg("群发完毕~");
}

private string getIPAddress()
{
  IPAddress addr;
  addr = new IPAddress(Dns.GetHostEntry(Dns.GetHostName()).AddressList[0].Address);
  return addr.ToString();
}

private void Form1_Load(object sender,EventArgs e)
{
  txtIP.Text = getIPAddress();
}

 客户端程序:

Thread threadClient = null;//客户端负责接收服务器发来消息的线程
Socket socketClient = null;//客户端负责通讯的套接字
private void btnConnect_Click(object sender,EventArgs)
{
  IPAddress address = IPAddress.Parse(txtIP.Text.Trim());//服务器端IP
  IPEndPoint endpoint = new IPEndPoint(address,int.Parse(txtPort.Text.Trim()));
  socketClient = new Socket(AddressFamily.InterNetwork,SocketType.Stream,ProtocolType.Tcp);
  socketClient.Connect(endpoint);

  threadCLient = new Thread(RecMsg);
  threadClient.IsBackground = true;
  threadClient.Start();
}

//接收服务器发来的消息
void RecMsg()
{
  while(true)
  {
    byte[] arrMsgRec = new byte[1024*1024*2];//2M
    int length = socketClient.Receive(arrMsgRec);
    string strMsgRec = System.Text.Encoding.UTF8.GetString(arrMsgRec,0,length);
    ShowMsg("收到:"+strMsgRec);
  }
}

void ShowMsg(string msg)
{
  txtMsg.AppendText(msg+"\r\n");
}

//向服务器发送文本消息
private void btnSend_Click(object sender,EventArgs e)
{
  string strMsg = txtMsgSend.Text.Trim();
  byte[] arrMsg = System.Text.Encoding.UTF8.GetBytes(strMsg);
  byte[] arrMsgSend = new byte[arrMsg.Length + 1];
  arrMsgSend[0] = 0;//0代表文字
  Buffer.BlockCopy(arrMsg,0,arrMsgSend,1,arrMsg.Length);
  socketClient.Send(arrmsgSend);
  ShowMsg("发送:"+strMsg);
}

//选择文件
private void btnChooseFile_Click(object sender,EventArgs e)
{
  OpenFIleDialog ofd = new OpenFileDialog();
  if(ofd.ShowDialog()==System.Windows.Forms.DialogResult.OK)
  {
    txtCHooseFIle.Text = ofd.FileName;
  }
}

//发送文件
private void btnSendFile_Click(object sender,EventArgs e)
{
  using(FileStream fs = new FileStream(txtChooseFile.Text,FileMode.Open))
  {
    byte[] arrFile = new byte[1024*1024*2];
    int length = fs.Read(arrFile,0,arrFile.Length);
    byte[] arrFileSend = new byte[length + 1];
    arrFileSend[0] = 1;
    Buffer.BlockCopy(arrFile,0,arrFileSend,1,length);
    socketClient.Send(arrFileSend);
  }
}
原文地址:https://www.cnblogs.com/zpehome/p/2873173.html