C# Socket 编程 Sample

使用Socket通信的服务器端编程,熟悉了服务器端和客户端的通信流程,实现了收发信息、文件传送以及震动功能

服务器端先创建Socket,然后将其和本地ip地址以及端口号连接,也就是使用Bind方法,然后使用Listen方法监听。

用Accept方法接受客户端的连接申请,并且等待客户端连接(在winform中,由于Accept方法是阻塞方法,必须创建一个线程来执行,防止主窗体卡死)

客户端连接成功Accept方法会返回一个用于发送和接收消息的Socket,之后就要用这个socket进行通信

在通信过程中要像实现不同功能,比如传送文件,就要在发送的字节流中使用一定的位置来存储信息,也就是使用自己的协议,在这个案例中,取第一个字节标识信息,0代表发送信息,1代表传递文件,2代表震动窗体

服务端代码如下

 1 using System; 2 using System.Collections.Generic; 3 using System.ComponentModel; 4 using System.Data; 5 using System.Drawing; 6 using System.Linq; 7 using System.Text; 8 using System.Threading.Tasks; 9 using System.Windows.Forms; 10 using System.Net.Sockets; 11 using System.Net; 12 using System.Threading; 13 using System.IO; 14  15 namespace ServerReview 16 { 17 public partial class Form1 : Form 18  { 19 public Form1() 20  { 21  InitializeComponent(); 22  } 23 private Socket socketSend; 24 private Socket socketWatch; 25 private Dictionary<string, Socket> socketClientList = new Dictionary<string, Socket>(); 26 private void btnStart_Click(object sender, EventArgs e) 27  { 28 socketWatch = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); 29 IPAddress ip = IPAddress.Any; 30 IPEndPoint iep = new IPEndPoint(ip, Convert.ToInt32(txtPort.Text)); 31 //将套接字和本机地址绑定 32  socketWatch.Bind(iep); 33 ShowMsg("监听成功"); 34 //用Listen监听 35 socketWatch.Listen(10); 36 //创建新线程不停接受客户端请求 37 Thread thread = new Thread(ServerAccept); 38 thread.IsBackground = true; 39  thread.Start(); 40  } 41 private void ServerAccept() 42  { 43 while (true) 44  { 45 socketSend = socketWatch.Accept(); 46  socketClientList.Add(socketSend.RemoteEndPoint.ToString(), socketSend); 47  cboUsers.Items.Add(socketSend.RemoteEndPoint.ToString()); 48 ShowMsg(socketSend.RemoteEndPoint.ToString() + "连接成功"); 49 //开启新线程不停接收消息 50 Thread thread = new Thread(ServerReceive); 51 thread.IsBackground = true; 52  thread.Start(); 53  } 54  } 55 private void ServerReceive() 56  { 57 while (true) 58  { 59 try 60  { 61 byte[] buffer = new byte[1024 * 1024 * 2]; 62 int byteNum = socketSend.Receive(buffer); 63 if (byteNum == 0) 64  { 65 break; 66  } 67 string str = Encoding.UTF8.GetString(buffer, 0, byteNum); 68 ShowMsg(socketSend.RemoteEndPoint.ToString() + ":" + str); 69  } 70 catch { } 71  } 72  } 73 private void ShowMsg(string str) 74  { 75 txtLog.AppendText(str + "\r\n"); 76  } 77  78 private void Form1_Load(object sender, EventArgs e) 79  { 80 Control.CheckForIllegalCrossThreadCalls = false; 81  } 82  83 private void btnSend_Click(object sender, EventArgs e) 84  { 85 string str = txtMsg.Text; 86 List<byte> list = new List<byte>(); 87 list.Add(0); 88 byte[] buffer = Encoding.UTF8.GetBytes(str); 89  list.AddRange(buffer); 90 byte[] newBuffer = list.ToArray(); 91 string ip = cboUsers.SelectedItem.ToString(); 92  socketClientList[ip].Send(newBuffer); 93  } 94  95 private void btnSelectFile_Click(object sender, EventArgs e) 96  { 97 OpenFileDialog ofd = new OpenFileDialog(); 98 ofd.InitialDirectory = @"D:\"; 99 ofd.Title = "请选择要发送的文件";100 ofd.Filter = "所有文件|*.*";101  ofd.ShowDialog();102 txtFilePath.Text = ofd.FileName;103  }104 105 private void btnSendFile_Click(object sender, EventArgs e)106  {107 string path = txtFilePath.Text;108 using(FileStream fsRead = new FileStream(path, FileMode.Open, FileAccess.Read))109  {110 try111  {112 byte[] buffer = new byte[1024 * 1024 * 5];113 int l = fsRead.Read(buffer, 0, buffer.Length);114 List<byte> list = new List<byte>();115 list.Add(1);116  list.AddRange(buffer);117 byte[] newBuffer = list.ToArray();118 socketClientList[cboUsers.SelectedItem.ToString()].Send(newBuffer,0,l+1,SocketFlags.None);119  }120 catch { }121  }122  }123 124 private void btnShake_Click(object sender, EventArgs e)125  {126 byte[] buffer = new byte[1];127 buffer[0] = 2;128  socketClientList[cboUsers.SelectedItem.ToString()].Send(buffer);129  }130  }131 }

客户端代码如下:

 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 15 namespace ClientRevier16 {17 public partial class Form1 : Form18  {19 public Form1()20  {21  InitializeComponent();22  }23 24 private void Form1_Load(object sender, EventArgs e)25  {26 Control.CheckForIllegalCrossThreadCalls = false;27  }28 private Socket socketClient;29 private void btnStart_Click(object sender, EventArgs e)30  {31 socketClient = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);32 IPAddress ip = IPAddress.Parse(txtServer.Text);33 IPEndPoint iep = new IPEndPoint(ip, Convert.ToInt32(txtPort.Text));34  socketClient.Connect(iep);35 ShowMsg("连接成功");36 //因为要不停接受消息,所以用while循环,并且为了接受消息的同时能做其他事,把这个放到线程中执行37 Thread thread = new Thread(ClientRecieve);38 thread.IsBackground = true;39  thread.Start();40  }41 private void ClientRecieve()42  {43 while (true)44  {45 byte[] buffer = new byte[1024 * 1024 * 2];46 int byteNum = socketClient.Receive(buffer);47 if (byteNum == 0)48  {49 break;50  }51 switch (buffer[0])52  {53 case 0:54 string str = Encoding.UTF8.GetString(buffer, 1, byteNum-1);55 ShowMsg(socketClient.RemoteEndPoint + ":" + str);56 break;57 case 1:58 SaveFileDialog sfd = new SaveFileDialog();59 sfd.InitialDirectory = @"D\";60 sfd.Title = "请选择需要保存的路径";61 sfd.Filter = "文本文件|*.txt|图片文件|*.jpg|所有文件|*.*";62 sfd.ShowDialog(this);63 using(FileStream fsWrite = new FileStream(sfd.FileName, FileMode.OpenOrCreate, FileAccess.Write))64  {65 fsWrite.Write(buffer, 1, byteNum - 1);66 MessageBox.Show("保存成功");67  }68 break;69 case 2:70 for(int i = 0; i < 1000; i++)71  {72 this.Location = new Point(200, 200);73 this.Location = new Point(230, 230);74  }75 break;76 default:break;77  }78 79  }80  }81 private void ShowMsg(string str)82  {83 txtLog.AppendText(str + "\r\n");84  }85 86 private void btnSend_Click(object sender, EventArgs e)87  {88 string str = txtMsg.Text;89 byte[] buffer = Encoding.UTF8.GetBytes(str);90  socketClient.Send(buffer);91 92  }93  }94 }

 

相关文章