
正文
[C#] Socket 通讯,一个简单的聊天窗口小程序
提示:扫一扫查出行【扫一扫了解最新限行尾号】
复制提示
Socket,这玩意,当时不会的时候,抄别人的都用不好,简单的一句话形容就是“笨死了”;也是很多人写的太复杂,不容易理解造成的。最近在搞erlang和C的通讯,也想试试erlang是不是可以和C#简单通讯,就简单的做了些测试用例,比较简单,觉得新手也可以接受。
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Net.Sockets;
using System.Net;
using System.Threading; namespace ChatClient
{
public partial class Form1 : Form
{
private System.Windows.Forms.RichTextBox richTextBox1;
private System.Windows.Forms.TextBox textBox1;
private System.ComponentModel.IContainer components = null; /// <summary>
/// 服务端侦听端口
/// </summary>
private const int _serverPort = ;
/// <summary>
/// 客户端侦听端口
/// </summary>
private const int _clientPort = ;
/// <summary>
/// 缓存大小
/// </summary>
private const int _bufferSize = ;
/// <summary>
/// 服务器IP
/// </summary>
private const string ServerIP = "172.17.47.199"; //手动修改为指定服务器ip private Thread thread; private void Form1_Load(object sender, EventArgs e)
{
thread = new Thread(new ThreadStart(delegate { Listenning(); }));
thread.Start();
} void textBox_KeyUp(object sender, KeyEventArgs e)
{
if (e.KeyCode == Keys.Enter)
{
string msg;
if ((msg = textBox1.Text.Trim()).Length > )
{
SendMessage(msg);
}
textBox1.Clear();
}
} void SendMessage(string msg)
{
try
{
Socket socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
IPEndPoint endPoint = new IPEndPoint(IPAddress.Parse(ServerIP), _serverPort);
socket.Connect(endPoint);
byte[] buffer = System.Text.ASCIIEncoding.UTF8.GetBytes(msg);
socket.Send(buffer);
socket.Close();
}
catch
{ }
} void Listenning()
{
TcpListener listener = new TcpListener(_clientPort);
listener.Start();
while (true)
{
Socket socket = listener.AcceptSocket();
byte[] buffer = new byte[_bufferSize];
socket.Receive(buffer);
int lastNullIndex = _bufferSize - ;
while (true)
{
if (buffer[lastNullIndex] != '\0')
break;
lastNullIndex--;
}
string msg = Encoding.UTF8.GetString(buffer, , lastNullIndex + );
WriteLine(msg);
socket.Close();
}
} void WriteLine(string msg)
{
this.Invoke(new MethodInvoker(delegate
{
this.richTextBox1.AppendText(msg + Environment.NewLine);
}));
} public Form1()
{
this.richTextBox1 = new System.Windows.Forms.RichTextBox();
this.textBox1 = new System.Windows.Forms.TextBox();
this.SuspendLayout();
//
// richTextBox1
//
this.richTextBox1.Location = new System.Drawing.Point(, );
this.richTextBox1.Name = "richTextBox1";
this.richTextBox1.Size = new System.Drawing.Size(, );
this.richTextBox1.TabIndex = ;
this.richTextBox1.Text = "";
this.richTextBox1.KeyUp += new System.Windows.Forms.KeyEventHandler(this.textBox_KeyUp);
//
// textBox1
//
this.textBox1.Location = new System.Drawing.Point(, );
this.textBox1.Multiline = true;
this.textBox1.Name = "textBox1";
this.textBox1.Size = new System.Drawing.Size(, );
this.textBox1.TabIndex = ;
this.textBox1.KeyUp += new System.Windows.Forms.KeyEventHandler(this.textBox_KeyUp);
//
// Form1
//
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 12F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.ClientSize = new System.Drawing.Size(, );
this.Controls.Add(this.richTextBox1);
this.Controls.Add(this.textBox1);
this.Name = "Form1";
this.Text = "Form1";
this.Load += new System.EventHandler(this.Form1_Load);
this.ResumeLayout(false);
this.PerformLayout();
} protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
}
}
Client端
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Diagnostics;
using System.Linq;
using System.ServiceProcess;
using System.Text;
using System.Net;
using System.Net.Sockets;
using System.Collections; namespace ChatService
{
public partial class Service1 : ServiceBase
{
/// <summary>
/// 服务端侦听端口
/// </summary>
private const int _serverPort = ;
/// <summary>
/// 客户端侦听端口
/// </summary>
private const int _clientPort = ;
/// <summary>
/// 缓存大小
/// </summary>
private const int _bufferSize = ;
/// <summary>
/// 服务器IP
/// </summary>
private const string ServerIP = "172.17.47.199"; //手动修改为指定服务器ip
/// <summary>
/// 客户端IP
/// </summary>
//private Hashtable ServerIPs = new Hashtable(); //存放ip + port
private List<string> ServerIPs = new List<string>(); public Service1()
{
//InitializeComponent(); //从控制台改为服务,需要注释下面的一行,打开本行
Listenning();
} void SendMessage(string from, string msg)
{ for (int i = ServerIPs.Count - ; i >= ; i--)
{
try
{
Socket socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
IPEndPoint endPoint = new IPEndPoint(IPAddress.Parse(ServerIPs[i]), _clientPort);
socket.Connect(endPoint);
byte[] buffer = System.Text.ASCIIEncoding.UTF8.GetBytes((from + " say: " + msg).Trim());
socket.Send(buffer);
socket.Close();
}
catch
{
ServerIPs.RemoveAt(i);
}
}
} void Listenning()
{ TcpListener listener = new TcpListener(_serverPort);
listener.Start();
while (true)
{
Socket socket = listener.AcceptSocket();
var s = socket.RemoteEndPoint.ToString();
var ipstr = s.Substring(, s.IndexOf(":")); if (!ServerIPs.Contains(ipstr))
{
ServerIPs.Add(ipstr);
} byte[] buffer = new byte[_bufferSize];
socket.Receive(buffer);
int lastNullIndex = _bufferSize - ; while (true)
{
if (buffer[lastNullIndex] != '\0')
break;
lastNullIndex--;
}
string msg = Encoding.UTF8.GetString(buffer, , lastNullIndex + );
SendMessage(ipstr,msg);
Console.WriteLine(msg);//服务模式下关闭
}
} protected override void OnStart(string[] args)
{
Listenning();
} protected override void OnStop()
{ }
}
}
Server端
逻辑视图(比较简单):

1.左上角的是一个远程客户端,右上角是本地客户端,右下角是本地服务端(暂时改为控制台程序)
2.这段程序只给不懂得如何用socket玩玩
3.这里面剔除了数据加密、异步获取等繁杂的过程,想要学习可以参照:http://yunpan.cn/cKT2ZHdKRMILz 访问密码 b610







