C#中Socket的简单使用
- 服务端监听某个端口
- 客户端向服务端地址和端口发起Socket连接请求
- 服务端收到连接请求后创建Socket连接,并维护这个连接队列。
- 客户端和服务端已经建立双工通信(即双向通信),客户端和服务端可以轻松方便的给彼此发送信息
端口
- 动态端口 从49152-65535
- 机器通常从1024起分配动态端口
- 公认端口:0-1023,注册端口: 1024-49151
,SUN的RPC端口从 32768开始 - 查看端口方式: netstat -a -n
http协议
Demo
服务端代码:
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;
using System.Net.Sockets;
using System.Threading;
namespace ChatMain
{
public partial class ChatMain : Form
{
public ChatMain()
{
InitializeComponent();
Control.CheckForIllegalCrossThreadCalls = false;
}
List<Socket> clientSocketList = new List<Socket>();
private void btnStart_Click(object sender, EventArgs e)
{
string ip = this.txtIP.Text;
//创建IP
IPAddress ipAddress = IPAddress.Parse(ip);
//创建代表本机的节点对象:包含IP和端口
IPEndPoint endPoint=new IPEndPoint(ipAddress,int.Parse(this.txtPort.Text));
//创建Socket:第一参数:寻址方式,第二个参数: socket传输方式Stream Tcp方式 Dgram:UDP 第三个参数:协议
Socket socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
//绑定端口和IP
socket.Bind(endPoint);
//开启监听,请求连接的队列的长度
socket.Listen(10);
//线程池开启 监听客户端连接
ThreadPool.QueueUserWorkItem(new WaitCallback(this.statAccept), socket);
this.txtLog.Text += "服务端开启监听客户端连接了..\r\n";
}
public void statAccept(object obj)
{
Socket socket = (Socket)obj;
try
{
while (true)
{
//接受客户端的一个连接
Socket proxSocket = socket.Accept();
//客户端代理socket对象的队列里面去
clientSocketList.Add(proxSocket);
//拿到客户端的端口和ip
this.txtLog.Text += proxSocket.RemoteEndPoint.ToString() + "\r\n";
//跟客户端进行通信 通过:proxSocket
//proxSocket.Send()
//proxSocket.Receive()
ThreadPool.QueueUserWorkItem(new WaitCallback(this.StartReciveClientData), proxSocket);
}
}
catch (Exception ex)
{
socket.Close();
}
}
/// <summary>
/// 接受连接过来的IP的数据
/// </summary>
public void StartReciveClientData(object obj)
{
Socket sokcet = (Socket)obj;
while (true)
{
byte[] buffer = new byte[1024 * 1024 * 1];
int realLenth= sokcet.Receive(buffer,0,buffer.Length,SocketFlags.None);
string strResult = Encoding.Default.GetString(buffer, 0, realLenth);
this.txtLog.Text += sokcet.RemoteEndPoint.ToString() + ":" + strResult + "\r\n";
}
}
private void btnStarClient_Click(object sender, EventArgs e)
{
ChatClient client = new ChatClient();
client.Show();
}
private void btnSend_Click(object sender, EventArgs e)
{
foreach (var socket in clientSocketList)
{
string strText = this.txtMsg.Text;
byte[] data = Encoding.Default.GetBytes(strText);
socket.Send(data, 0, data.Length, SocketFlags.None);
}
}
}
}
客户端代码:
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 ChatMain
{
public partial class ChatClient : Form
{
public Socket CurrentSocket {get;set; }
public ChatClient()
{
InitializeComponent();
}
private void btnConnect_Click(object sender, EventArgs e)
{
Socket socket = null;
IPAddress ipAddress = IPAddress.Parse(this.txtIP.Text);
IPEndPoint endPoint=new IPEndPoint(ipAddress,int.Parse(this.txtPort.Text));
//创建个Socket
socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
socket.Connect(endPoint);
ThreadPool.QueueUserWorkItem(new WaitCallback(Recive), socket);
this.lbStatus.Text = "已连接";
CurrentSocket = socket;
}
//接受
public void Recive(object obj) {
Socket socket = (Socket)obj;
while (socket != null && socket.Connected)
{
byte[] buffer = new byte[1024 * 1024];
int realLength = socket.Receive(buffer, 0, buffer.Length,SocketFlags.None);
//接受字符串
string txt = Encoding.Default.GetString(buffer, 0, realLength);
this.txtLog.Text += string.Format("接受消息:{0}", txt);
this.txtLog.Text += "\r\n";
}
}
//发送
private void btnSend_Click(object sender, EventArgs e)
{
string strText = this.txtMsg.Text;
if (string.IsNullOrEmpty(strText)) {
this.txtLog.Text = "发送的消息不能为空";
}
if (CurrentSocket == null)
{
MessageBox.Show("请先连接服务端");
return;
}
byte[] data = Encoding.Default.GetBytes(strText);
try
{
CurrentSocket.Send(data, 0, data.Length, 0);
}
catch (Exception)
{
}
}
}
}