1.服务器
using System;using System.Collections.Generic;using System.ComponentModel;using System.Data;using System.Drawing;using System.IO;using System.Linq;using System.Net;using System.Net.Sockets;using System.Text;using System.Threading;using System.Threading.Tasks;using System.Windows.Forms;namespace Server{public partial class Form1 : Form{public Form1(){InitializeComponent();}private void btnStart_Click(object sender, EventArgs e){try{//当点击开始监听的时候 在服务器端创建一个负责监IP地址跟端口号的SocketSocket socketWatch = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);IPAddress ip = IPAddress.Any;//IPAddress.Parse(txtServer.Text);//创建端口号对象IPEndPoint point = new IPEndPoint(ip, Convert.ToInt32(txtPort.Text));//监听socketWatch.Bind(point);ShowMsg("监听成功");socketWatch.Listen(10);Thread th = new Thread(Listen);th.IsBackground = true;th.Start(socketWatch);}catch{ }}/// <summary>/// 等待客户端的连接 并且创建与之通信用的Socket/// </summary>///Socket socketSend;void Listen(object o){Socket socketWatch = o as Socket;//等待客户端的连接 并且创建一个负责通信的Socketwhile (true){try{//负责跟客户端通信的SocketsocketSend = socketWatch.Accept();//将远程连接的客户端的IP地址和Socket存入集合中dicSocket.Add(socketSend.RemoteEndPoint.ToString(), socketSend);//将远程连接的客户端的IP地址和端口号存储下拉框中cboUsers.Items.Add(socketSend.RemoteEndPoint.ToString());//192.168.11.78:连接成功ShowMsg(socketSend.RemoteEndPoint.ToString() + ":" + "连接成功");//开启 一个新线程不停的接受客户端发送过来的消息Thread th = new Thread(Recive);th.IsBackground = true;th.Start(socketSend);}catch{ }}}//将远程连接的客户端的IP地址和Socket存入集合中Dictionary<string, Socket> dicSocket = new Dictionary<string, Socket>();/// <summary>/// 服务器端不停的接受客户端发送过来的消息/// </summary>/// <param name="o"></param>void Recive(object o){Socket socketSend = o as Socket;while (true){try{//客户端连接成功后,服务器应该接受客户端发来的消息byte[] buffer = new byte[1024 * 1024 * 2];//实际接受到的有效字节数int r = socketSend.Receive(buffer);if (r == 0){break;}string str = Encoding.UTF8.GetString(buffer, 0, r);ShowMsg(socketSend.RemoteEndPoint + ":" + str);}catch{ }}}void ShowMsg(string str){txtLog.AppendText(str + "\r\n");}private void Form1_Load(object sender, EventArgs e){Control.CheckForIllegalCrossThreadCalls = false;}/// <summary>/// 服务器给客户端发送消息/// </summary>/// <param name="sender"></param>/// <param name="e"></param>private void btnSend_Click(object sender, EventArgs e){string str = txtMsg.Text;byte[] buffer = System.Text.Encoding.UTF8.GetBytes(str);List<byte> list = new List<byte>();list.Add(0);list.AddRange(buffer);//将泛型集合转换为数组byte[] newBuffer = list.ToArray();//buffer = list.ToArray();不可能//获得用户在下拉框中选中的IP地址string ip = cboUsers.SelectedItem.ToString();dicSocket[ip].Send(newBuffer);// socketSend.Send(buffer);}/// <summary>/// 选择要发送的文件/// </summary>/// <param name="sender"></param>/// <param name="e"></param>private void btnSelect_Click(object sender, EventArgs e){OpenFileDialog ofd = new OpenFileDialog();ofd.InitialDirectory = @"C:\Users\SpringRain\Desktop";ofd.Title = "请选择要发送的文件";ofd.Filter = "所有文件|*.*";ofd.ShowDialog();txtPath.Text = ofd.FileName;}private void btnSendFile_Click(object sender, EventArgs e){//获得要发送文件的路径string path = txtPath.Text;using (FileStream fsRead = new FileStream(path, FileMode.Open, FileAccess.Read)){byte[] buffer = new byte[1024 * 1024 * 5];int r = fsRead.Read(buffer, 0, buffer.Length);List<byte> list = new List<byte>();list.Add(1);list.AddRange(buffer);byte[] newBuffer = list.ToArray();dicSocket[cboUsers.SelectedItem.ToString()].Send(newBuffer, 0, r+1, SocketFlags.None);}}/// <summary>/// 发送震动/// </summary>/// <param name="sender"></param>/// <param name="e"></param>private void btnZD_Click(object sender, EventArgs e){byte[] buffer = new byte[1];buffer[0] = 2;dicSocket[cboUsers.SelectedItem.ToString()].Send(buffer);}private void txtServer_TextChanged(object sender, EventArgs e){}}}
解释:
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.客户端
using System;using System.Collections.Generic;using System.ComponentModel;using System.Data;using System.Drawing;using System.IO;using System.Linq;using System.Net;using System.Net.Sockets;using System.Text;using System.Threading;using System.Threading.Tasks;using System.Windows.Forms;namespace _07Client{public partial class Form1 : Form{public Form1(){InitializeComponent();}Socket socketSend;private void btnStart_Click(object sender, EventArgs e){try{//创建负责通信的SocketsocketSend = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);IPAddress ip = IPAddress.Parse(txtServer.Text);IPEndPoint point = new IPEndPoint(ip, Convert.ToInt32(txtPort.Text));//获得要连接的远程服务器应用程序的IP地址和端口号socketSend.Connect(point);ShowMsg("连接成功");//开启一个新的线程不停的接收服务端发来的消息Thread th = new Thread(Recive);th.IsBackground = true;th.Start();}catch{ }}/// <summary>/// 不停的接受服务器发来的消息/// </summary>void Recive(){while (true){try{byte[] buffer = new byte[1024 * 1024 * 3];int r = socketSend.Receive(buffer);//实际接收到的有效字节数if (r == 0){break;}//表示发送的文字消息if (buffer[0] == 0){string s = Encoding.UTF8.GetString(buffer, 1, r-1);ShowMsg(socketSend.RemoteEndPoint + ":" + s);}else if (buffer[0] == 1){SaveFileDialog sfd = new SaveFileDialog();sfd.InitialDirectory = @"C:\Users\SpringRain\Desktop";sfd.Title = "请选择要保存的文件";sfd.Filter = "所有文件|*.*";sfd.ShowDialog(this);string path = sfd.FileName;using (FileStream fsWrite = new FileStream(path, FileMode.OpenOrCreate, FileAccess.Write)){fsWrite.Write(buffer, 1, r - 1);}MessageBox.Show("保存成功");}else if (buffer[0] == 2){ZD();}}catch { }}}/// <summary>/// 震动/// </summary>void ZD(){for (int i = 0; i < 500; i++){this.Location = new Point(200, 200);this.Location = new Point(280, 280);}}void ShowMsg(string str){txtLog.AppendText(str + "\r\n");}/// <summary>/// 客户端给服务器发送消息/// </summary>/// <param name="sender"></param>/// <param name="e"></param>private void btnSend_Click(object sender, EventArgs e){string str = txtMsg.Text.Trim();byte[] buffer = System.Text.Encoding.UTF8.GetBytes(str);socketSend.Send(buffer);}private void Form1_Load(object sender, EventArgs e){Control.CheckForIllegalCrossThreadCalls = false;}}}
