[C#] Socket 通讯,一个简单的聊天窗口小程序
Socket,这玩意,当时不会的时候,抄别人的都用不好,简单的一句话形容就是“笨死了”;也是很多人写的太复杂,不容易理解造成的。最近在搞erlang和C的通讯,也想试试erlang是不是可以和C#简单通讯,就简单的做了些测试用例,比较简单,觉得新手也可以接受。
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.Windows.Forms; 9 using System.Net.Sockets; 10 using System.Net; 11 using System.Threading; 12 13 namespace ChatClient 14 { 15 public partial class Form1 : Form 16 { 17 private System.Windows.Forms.RichTextBox richTextBox1; 18 private System.Windows.Forms.TextBox textBox1; 19 private System.ComponentModel.IContainer components = null; 20 21 /// <summary> 22 /// 服务端侦听端口 23 /// </summary> 24 private const int _serverPort = 8707; 25 /// <summary> 26 /// 客户端侦听端口 27 /// </summary> 28 private const int _clientPort = 8708; 29 /// <summary> 30 /// 缓存大小 31 /// </summary> 32 private const int _bufferSize = 1024; 33 /// <summary> 34 /// 服务器IP 35 /// </summary> 36 private const string ServerIP = "172.17.47.199"; //手动修改为指定服务器ip 37 38 private Thread thread; 39 40 private void Form1_Load(object sender, EventArgs e) 41 { 42 thread = new Thread(new ThreadStart(delegate { Listenning(); })); 43 thread.Start(); 44 } 45 46 void textBox_KeyUp(object sender, KeyEventArgs e) 47 { 48 if (e.KeyCode == Keys.Enter) 49 { 50 string msg; 51 if ((msg = textBox1.Text.Trim()).Length > 0) 52 { 53 SendMessage(msg); 54 } 55 textBox1.Clear(); 56 } 57 } 58 59 void SendMessage(string msg) 60 { 61 try 62 { 63 Socket socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); 64 IPEndPoint endPoint = new IPEndPoint(IPAddress.Parse(ServerIP), _serverPort); 65 socket.Connect(endPoint); 66 byte[] buffer = System.Text.ASCIIEncoding.UTF8.GetBytes(msg); 67 socket.Send(buffer); 68 socket.Close(); 69 } 70 catch 71 { } 72 } 73 74 void Listenning() 75 { 76 TcpListener listener = new TcpListener(_clientPort); 77 listener.Start(); 78 while (true) 79 { 80 Socket socket = listener.AcceptSocket(); 81 byte[] buffer = new byte[_bufferSize]; 82 socket.Receive(buffer); 83 int lastNullIndex = _bufferSize - 1; 84 while (true) 85 { 86 if (buffer[lastNullIndex] != '\0') 87 break; 88 lastNullIndex--; 89 } 90 string msg = Encoding.UTF8.GetString(buffer, 0, lastNullIndex + 1); 91 WriteLine(msg); 92 socket.Close(); 93 } 94 } 95 96 void WriteLine(string msg) 97 { 98 this.Invoke(new MethodInvoker(delegate 99 { 100 this.richTextBox1.AppendText(msg + Environment.NewLine); 101 })); 102 } 103 104 public Form1() 105 { 106 this.richTextBox1 = new System.Windows.Forms.RichTextBox(); 107 this.textBox1 = new System.Windows.Forms.TextBox(); 108 this.SuspendLayout(); 109 // 110 // richTextBox1 111 // 112 this.richTextBox1.Location = new System.Drawing.Point(1, 2); 113 this.richTextBox1.Name = "richTextBox1"; 114 this.richTextBox1.Size = new System.Drawing.Size(282, 188); 115 this.richTextBox1.TabIndex = 3; 116 this.richTextBox1.Text = ""; 117 this.richTextBox1.KeyUp += new System.Windows.Forms.KeyEventHandler(this.textBox_KeyUp); 118 // 119 // textBox1 120 // 121 this.textBox1.Location = new System.Drawing.Point(3, 196); 122 this.textBox1.Multiline = true; 123 this.textBox1.Name = "textBox1"; 124 this.textBox1.Size = new System.Drawing.Size(277, 65); 125 this.textBox1.TabIndex = 2; 126 this.textBox1.KeyUp += new System.Windows.Forms.KeyEventHandler(this.textBox_KeyUp); 127 // 128 // Form1 129 // 130 this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 12F); 131 this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; 132 this.ClientSize = new System.Drawing.Size(284, 262); 133 this.Controls.Add(this.richTextBox1); 134 this.Controls.Add(this.textBox1); 135 this.Name = "Form1"; 136 this.Text = "Form1"; 137 this.Load += new System.EventHandler(this.Form1_Load); 138 this.ResumeLayout(false); 139 this.PerformLayout(); 140 } 141 142 protected override void Dispose(bool disposing) 143 { 144 if (disposing && (components != null)) 145 { 146 components.Dispose(); 147 } 148 base.Dispose(disposing); 149 } 150 } 151 }
1 using System; 2 using System.Collections.Generic; 3 using System.ComponentModel; 4 using System.Data; 5 using System.Diagnostics; 6 using System.Linq; 7 using System.ServiceProcess; 8 using System.Text; 9 using System.Net; 10 using System.Net.Sockets; 11 using System.Collections; 12 13 namespace ChatService 14 { 15 public partial class Service1 : ServiceBase 16 { 17 /// <summary> 18 /// 服务端侦听端口 19 /// </summary> 20 private const int _serverPort = 8707; 21 /// <summary> 22 /// 客户端侦听端口 23 /// </summary> 24 private const int _clientPort = 8708; 25 /// <summary> 26 /// 缓存大小 27 /// </summary> 28 private const int _bufferSize = 1024; 29 /// <summary> 30 /// 服务器IP 31 /// </summary> 32 private const string ServerIP = "172.17.47.199"; //手动修改为指定服务器ip 33 /// <summary> 34 /// 客户端IP 35 /// </summary> 36 //private Hashtable ServerIPs = new Hashtable(); //存放ip + port 37 private List<string> ServerIPs = new List<string>(); 38 39 public Service1() 40 { 41 //InitializeComponent(); //从控制台改为服务,需要注释下面的一行,打开本行 42 Listenning(); 43 } 44 45 void SendMessage(string from, string msg) 46 { 47 48 for (int i = ServerIPs.Count - 1; i >= 0; i--) 49 { 50 try 51 { 52 Socket socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); 53 IPEndPoint endPoint = new IPEndPoint(IPAddress.Parse(ServerIPs[i]), _clientPort); 54 socket.Connect(endPoint); 55 byte[] buffer = System.Text.ASCIIEncoding.UTF8.GetBytes((from + " say: " + msg).Trim()); 56 socket.Send(buffer); 57 socket.Close(); 58 } 59 catch 60 { 61 ServerIPs.RemoveAt(i); 62 } 63 } 64 } 65 66 void Listenning() 67 { 68 69 TcpListener listener = new TcpListener(_serverPort); 70 listener.Start(); 71 while (true) 72 { 73 Socket socket = listener.AcceptSocket(); 74 var s = socket.RemoteEndPoint.ToString(); 75 var ipstr = s.Substring(0, s.IndexOf(":")); 76 77 if (!ServerIPs.Contains(ipstr)) 78 { 79 ServerIPs.Add(ipstr); 80 } 81 82 byte[] buffer = new byte[_bufferSize]; 83 socket.Receive(buffer); 84 int lastNullIndex = _bufferSize - 1; 85 86 while (true) 87 { 88 if (buffer[lastNullIndex] != '\0') 89 break; 90 lastNullIndex--; 91 } 92 string msg = Encoding.UTF8.GetString(buffer, 0, lastNullIndex + 1); 93 SendMessage(ipstr,msg); 94 Console.WriteLine(msg);//服务模式下关闭 95 } 96 } 97 98 protected override void OnStart(string[] args) 99 { 100 Listenning(); 101 } 102 103 protected override void OnStop() 104 { 105 106 } 107 } 108 }
逻辑视图(比较简单):
1.左上角的是一个远程客户端,右上角是本地客户端,右下角是本地服务端(暂时改为控制台程序)
2.这段程序只给不懂得如何用socket玩玩
3.这里面剔除了数据加密、异步获取等繁杂的过程,想要学习可以参照:http://yunpan.cn/cKT2ZHdKRMILz 访问密码 b610