1.服务器

  1. using System;
  2. using System.Collections.Generic;
  3. using System.ComponentModel;
  4. using System.Data;
  5. using System.Drawing;
  6. using System.IO;
  7. using System.Linq;
  8. using System.Net;
  9. using System.Net.Sockets;
  10. using System.Text;
  11. using System.Threading;
  12. using System.Threading.Tasks;
  13. using System.Windows.Forms;
  14. namespace Server
  15. {
  16. public partial class Form1 : Form
  17. {
  18. public Form1()
  19. {
  20. InitializeComponent();
  21. }
  22. private void btnStart_Click(object sender, EventArgs e)
  23. {
  24. try
  25. {
  26. //当点击开始监听的时候 在服务器端创建一个负责监IP地址跟端口号的Socket
  27. Socket socketWatch = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
  28. IPAddress ip = IPAddress.Any;//IPAddress.Parse(txtServer.Text);
  29. //创建端口号对象
  30. IPEndPoint point = new IPEndPoint(ip, Convert.ToInt32(txtPort.Text));
  31. //监听
  32. socketWatch.Bind(point);
  33. ShowMsg("监听成功");
  34. socketWatch.Listen(10);
  35. Thread th = new Thread(Listen);
  36. th.IsBackground = true;
  37. th.Start(socketWatch);
  38. }
  39. catch
  40. { }
  41. }
  42. /// <summary>
  43. /// 等待客户端的连接 并且创建与之通信用的Socket
  44. /// </summary>
  45. ///
  46. Socket socketSend;
  47. void Listen(object o)
  48. {
  49. Socket socketWatch = o as Socket;
  50. //等待客户端的连接 并且创建一个负责通信的Socket
  51. while (true)
  52. {
  53. try
  54. {
  55. //负责跟客户端通信的Socket
  56. socketSend = socketWatch.Accept();
  57. //将远程连接的客户端的IP地址和Socket存入集合中
  58. dicSocket.Add(socketSend.RemoteEndPoint.ToString(), socketSend);
  59. //将远程连接的客户端的IP地址和端口号存储下拉框中
  60. cboUsers.Items.Add(socketSend.RemoteEndPoint.ToString());
  61. //192.168.11.78:连接成功
  62. ShowMsg(socketSend.RemoteEndPoint.ToString() + ":" + "连接成功");
  63. //开启 一个新线程不停的接受客户端发送过来的消息
  64. Thread th = new Thread(Recive);
  65. th.IsBackground = true;
  66. th.Start(socketSend);
  67. }
  68. catch
  69. { }
  70. }
  71. }
  72. //将远程连接的客户端的IP地址和Socket存入集合中
  73. Dictionary<string, Socket> dicSocket = new Dictionary<string, Socket>();
  74. /// <summary>
  75. /// 服务器端不停的接受客户端发送过来的消息
  76. /// </summary>
  77. /// <param name="o"></param>
  78. void Recive(object o)
  79. {
  80. Socket socketSend = o as Socket;
  81. while (true)
  82. {
  83. try
  84. {
  85. //客户端连接成功后,服务器应该接受客户端发来的消息
  86. byte[] buffer = new byte[1024 * 1024 * 2];
  87. //实际接受到的有效字节数
  88. int r = socketSend.Receive(buffer);
  89. if (r == 0)
  90. {
  91. break;
  92. }
  93. string str = Encoding.UTF8.GetString(buffer, 0, r);
  94. ShowMsg(socketSend.RemoteEndPoint + ":" + str);
  95. }
  96. catch
  97. { }
  98. }
  99. }
  100. void ShowMsg(string str)
  101. {
  102. txtLog.AppendText(str + "\r\n");
  103. }
  104. private void Form1_Load(object sender, EventArgs e)
  105. {
  106. Control.CheckForIllegalCrossThreadCalls = false;
  107. }
  108. /// <summary>
  109. /// 服务器给客户端发送消息
  110. /// </summary>
  111. /// <param name="sender"></param>
  112. /// <param name="e"></param>
  113. private void btnSend_Click(object sender, EventArgs e)
  114. {
  115. string str = txtMsg.Text;
  116. byte[] buffer = System.Text.Encoding.UTF8.GetBytes(str);
  117. List<byte> list = new List<byte>();
  118. list.Add(0);
  119. list.AddRange(buffer);
  120. //将泛型集合转换为数组
  121. byte[] newBuffer = list.ToArray();
  122. //buffer = list.ToArray();不可能
  123. //获得用户在下拉框中选中的IP地址
  124. string ip = cboUsers.SelectedItem.ToString();
  125. dicSocket[ip].Send(newBuffer);
  126. // socketSend.Send(buffer);
  127. }
  128. /// <summary>
  129. /// 选择要发送的文件
  130. /// </summary>
  131. /// <param name="sender"></param>
  132. /// <param name="e"></param>
  133. private void btnSelect_Click(object sender, EventArgs e)
  134. {
  135. OpenFileDialog ofd = new OpenFileDialog();
  136. ofd.InitialDirectory = @"C:\Users\SpringRain\Desktop";
  137. ofd.Title = "请选择要发送的文件";
  138. ofd.Filter = "所有文件|*.*";
  139. ofd.ShowDialog();
  140. txtPath.Text = ofd.FileName;
  141. }
  142. private void btnSendFile_Click(object sender, EventArgs e)
  143. {
  144. //获得要发送文件的路径
  145. string path = txtPath.Text;
  146. using (FileStream fsRead = new FileStream(path, FileMode.Open, FileAccess.Read))
  147. {
  148. byte[] buffer = new byte[1024 * 1024 * 5];
  149. int r = fsRead.Read(buffer, 0, buffer.Length);
  150. List<byte> list = new List<byte>();
  151. list.Add(1);
  152. list.AddRange(buffer);
  153. byte[] newBuffer = list.ToArray();
  154. dicSocket[cboUsers.SelectedItem.ToString()].Send(newBuffer, 0, r+1, SocketFlags.None);
  155. }
  156. }
  157. /// <summary>
  158. /// 发送震动
  159. /// </summary>
  160. /// <param name="sender"></param>
  161. /// <param name="e"></param>
  162. private void btnZD_Click(object sender, EventArgs e)
  163. {
  164. byte[] buffer = new byte[1];
  165. buffer[0] = 2;
  166. dicSocket[cboUsers.SelectedItem.ToString()].Send(buffer);
  167. }
  168. private void txtServer_TextChanged(object sender, EventArgs e)
  169. {
  170. }
  171. }
  172. }

解释:
1.
IPAddress.Any表示本机ip,换言之,如果服务器绑定此地址,则表示侦听本机所有ip对应的那个端口(本机可能有多个ip或只有一个ip)
IPAddress.Any微软给出的解释是:Provides an IP address that indicates that the server must listen for client activity on all network interfaces. This field is read-only.翻译过来就是:提供一个iP地址来指示服务器必须监听所有网卡上的客户端活动。此字段为只读的。也就是说,对双卡网或者多网卡的机器,每个网卡都会有一个独立的ip,如果使用了IPAddress.Any就表示服务器必须监听本机所有网卡上的指定端口。
比如双网卡机器,内网ip为192.168.0.1,外网ip为120.210.1.1,服务器可以同时监听192.168.0.1:80和120.210.1.1:80。

2.客户端

  1. using System;
  2. using System.Collections.Generic;
  3. using System.ComponentModel;
  4. using System.Data;
  5. using System.Drawing;
  6. using System.IO;
  7. using System.Linq;
  8. using System.Net;
  9. using System.Net.Sockets;
  10. using System.Text;
  11. using System.Threading;
  12. using System.Threading.Tasks;
  13. using System.Windows.Forms;
  14. namespace _07Client
  15. {
  16. public partial class Form1 : Form
  17. {
  18. public Form1()
  19. {
  20. InitializeComponent();
  21. }
  22. Socket socketSend;
  23. private void btnStart_Click(object sender, EventArgs e)
  24. {
  25. try
  26. {
  27. //创建负责通信的Socket
  28. socketSend = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
  29. IPAddress ip = IPAddress.Parse(txtServer.Text);
  30. IPEndPoint point = new IPEndPoint(ip, Convert.ToInt32(txtPort.Text));
  31. //获得要连接的远程服务器应用程序的IP地址和端口号
  32. socketSend.Connect(point);
  33. ShowMsg("连接成功");
  34. //开启一个新的线程不停的接收服务端发来的消息
  35. Thread th = new Thread(Recive);
  36. th.IsBackground = true;
  37. th.Start();
  38. }
  39. catch
  40. { }
  41. }
  42. /// <summary>
  43. /// 不停的接受服务器发来的消息
  44. /// </summary>
  45. void Recive()
  46. {
  47. while (true)
  48. {
  49. try
  50. {
  51. byte[] buffer = new byte[1024 * 1024 * 3];
  52. int r = socketSend.Receive(buffer);
  53. //实际接收到的有效字节数
  54. if (r == 0)
  55. {
  56. break;
  57. }
  58. //表示发送的文字消息
  59. if (buffer[0] == 0)
  60. {
  61. string s = Encoding.UTF8.GetString(buffer, 1, r-1);
  62. ShowMsg(socketSend.RemoteEndPoint + ":" + s);
  63. }
  64. else if (buffer[0] == 1)
  65. {
  66. SaveFileDialog sfd = new SaveFileDialog();
  67. sfd.InitialDirectory = @"C:\Users\SpringRain\Desktop";
  68. sfd.Title = "请选择要保存的文件";
  69. sfd.Filter = "所有文件|*.*";
  70. sfd.ShowDialog(this);
  71. string path = sfd.FileName;
  72. using (FileStream fsWrite = new FileStream(path, FileMode.OpenOrCreate, FileAccess.Write))
  73. {
  74. fsWrite.Write(buffer, 1, r - 1);
  75. }
  76. MessageBox.Show("保存成功");
  77. }
  78. else if (buffer[0] == 2)
  79. {
  80. ZD();
  81. }
  82. }
  83. catch { }
  84. }
  85. }
  86. /// <summary>
  87. /// 震动
  88. /// </summary>
  89. void ZD()
  90. {
  91. for (int i = 0; i < 500; i++)
  92. {
  93. this.Location = new Point(200, 200);
  94. this.Location = new Point(280, 280);
  95. }
  96. }
  97. void ShowMsg(string str)
  98. {
  99. txtLog.AppendText(str + "\r\n");
  100. }
  101. /// <summary>
  102. /// 客户端给服务器发送消息
  103. /// </summary>
  104. /// <param name="sender"></param>
  105. /// <param name="e"></param>
  106. private void btnSend_Click(object sender, EventArgs e)
  107. {
  108. string str = txtMsg.Text.Trim();
  109. byte[] buffer = System.Text.Encoding.UTF8.GetBytes(str);
  110. socketSend.Send(buffer);
  111. }
  112. private void Form1_Load(object sender, EventArgs e)
  113. {
  114. Control.CheckForIllegalCrossThreadCalls = false;
  115. }
  116. }
  117. }