C#之Socket编程
代码在VS编辑器上创建,选择“控制台控制程序”
代码注释比较详细,在此就不说废话了
首先粘贴服务端代码
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Threading;
using System.Net;
using System.Net.Sockets;
namespace ServerSocket
{
//接收,监听,发送的类,自己创建
public class StateObject
{
public byte[] buffer = new byte[128];
public int offset = 0;
public Socket socket = null;
public StateObject() { }
}
public class ServerSocketClass
{
//单利
public static ServerSocketClass instance = null;
//用于存放所有的线程
public List<Thread> threadList = new List<Thread>();
//用于存放所有的连接的Socket对象
public List<Socket> AcceptSocketList = new List<Socket>();
public Socket serverSocket;
//创建一个单利方法,避免重复创建对象
public static ServerSocketClass Init()
{
if (instance == null)
{
instance = new ServerSocketClass();
}
return instance;
}
public ServerSocketClass()
{
//端口号
int port = 11111;
//IP地址
IPAddress ipAddress = IPAddress.Parse("127.0.0.1");
//实例化Socket对象,参数1为Socket类的寻址方案,参数2指定Socket的类型,参数3为Socket使用的协议
Socket serverSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
//
IPEndPoint ipEndPoint = new IPEndPoint(ipAddress, port);
//服务端绑定IP和端口号
serverSocket.Bind(ipEndPoint);
//开始监听客户端的连接,并且设定最多可以接受10个客户端的连接
serverSocket.Listen(10);
Console.WriteLine("创建成功");
//创建一个线程,服务端开始接收连接
ParameterizedThreadStart threadStart = new ParameterizedThreadStart(SocketBeginAccept);
Thread thread = new Thread(threadStart);
thread.IsBackground = true;
thread.Start(serverSocket);
threadList.Add(thread);
}
//异步接受连接
public void SocketBeginAccept(object s)
{
Socket socket = (Socket)s;
try
{
while (true)
{
StateObject stateObject = new StateObject();
stateObject.socket = socket;
//开启异步接收连接
socket.BeginAccept(new AsyncCallback(AcceptCallBack), stateObject);
Thread.Sleep(100); //线程暂停 100 毫秒
}
}
catch
{ }
}
//异步连接的回调方法
public void AcceptCallBack(IAsyncResult acccept)
{
//获取 StateObject对象
StateObject stateObject = (StateObject)acccept.AsyncState;
serverSocket = stateObject.socket;
Socket clientSocket = serverSocket.EndAccept(acccept);
Console.WriteLine("接收到客户端连接 server {0}; client : {1}; 可以发消息啦", serverSocket.LocalEndPoint, clientSocket.RemoteEndPoint);
//将客户端连接存放进集合中
AcceptSocketList.Add(clientSocket);
//在回调方法中再次调用接收连接的线程
serverSocket.BeginAccept(new AsyncCallback(AcceptCallBack), stateObject);
}
//创建接收消息的线程
public void CreateThreadReceive(Socket clientSocket)
{
ParameterizedThreadStart threadStart = new ParameterizedThreadStart(SocketBeginReceive);
Thread thread = new Thread(threadStart);
thread.IsBackground = true;
thread.Start(clientSocket);
threadList.Add(thread);
}
//接收消息的线程调用该方法
public void SocketBeginReceive(object s)
{
Socket socket = (Socket)s;
StateObject stateObject = new StateObject();
stateObject.socket = socket;
try
{
while (true)
{
//异步接收客户端发来的信息
socket.BeginReceive(stateObject.buffer, 0, stateObject.buffer.Length, 0, new AsyncCallback(ReceiveCallBack), stateObject);
Thread.Sleep(100);
}
}
catch { CloseSocket(socket); }
}
//接收消息的回调方法
public void ReceiveCallBack(IAsyncResult receive)
{
StateObject stateObject = (StateObject)receive.AsyncState;
Socket s = stateObject.socket;
//回调方法中要调用该方法
int read = s.EndReceive(receive);
if (read > 0)
{
try
{
//开启异步接收消息
s.BeginReceive(stateObject.buffer, 0, stateObject.buffer.Length, 0, new AsyncCallback(ReceiveCallBack), stateObject);
}
catch { }
}
else
{
CloseSocket(s);
}
ASCIIEncoding encoding = new ASCIIEncoding();
string str = encoding.GetString(stateObject.buffer);
//输出客户端发来的消息
Console.WriteLine("客户端 :{0}", str);
}
//服务端向客户端发送消息
public void ServerSendMessage(Socket client, string message)
{
StateObject stateObject = new StateObject();
stateObject.socket = client;
try
{
//将字符串转换为字节
stateObject.buffer = Encoding.UTF8.GetBytes(message);
//开启异步发送
client.BeginSend(stateObject.buffer, 0, stateObject.buffer.Length, 0, new AsyncCallback(SendMessageCallBack), stateObject);
}
catch (Exception e)
{
Console.WriteLine("ddd {0}", e);
CloseSocket(client);
}
}
//服务端发送消息的回调方法
public void SendMessageCallBack(IAsyncResult send)
{
StateObject stateObject = (StateObject)send.AsyncState;
Socket client = stateObject.socket;
//int count = client.EndSend(send);//获取发送消息的长度,
//获取发送的消息, 转换为字符串
//string str = new ASCIIEncoding().GetString(stateObject.buffer);
//将发送的消息打印到控制台
//Console.WriteLine("服务端:发送消息长度{0}: 内容{1}", count.ToString(), new ASCIIEncoding().GetString(stateObject.buffer));
}
//销毁线程的方法
public void CloseThread()
{
foreach (Thread thread in threadList)
{
if (thread.IsAlive)
{
thread.Abort();
}
}
}
//断开Socket
public void CloseSocket(Socket s)
{
if (!s.Connected)
{
s.Shutdown(SocketShutdown.Both);
s.Close();
}
}
}
class Program
{
static void Main(string[] args)
{
//实例化客户端类对象
ServerSocketClass serverSocketClass = ServerSocketClass.Init();
//开启接收消息的方法
StartReceive(serverSocketClass);
string str = "";
while (true)
{
str = Console.ReadLine();
StartSendMessage(serverSocketClass, str);
Thread.Sleep(100);
}
}
//调用该方法接收客户端发来的消息
public static void StartReceive(ServerSocketClass serverSocketCla)
{
ServerSocketClass serverSocketClass = (ServerSocketClass)serverSocketCla;
while (true)
{
//为了能够监听连接的客户端发来的消息,在没有客户端连接时一直循环调用
if (serverSocketClass.AcceptSocketList.Count > 0)
{
foreach (Socket socket in serverSocketClass.AcceptSocketList)
{
serverSocketClass.CreateThreadReceive(socket);
}
//当有一个客户端连接到服务端时,退出循环
break;
}
Thread.Sleep(100);
}
}
//手动输入向客户端发送消息
public static void StartSendMessage(ServerSocketClass serverSocketCla, string message)
{
ServerSocketClass serverSocketClass = (ServerSocketClass)serverSocketCla;
//向所有连接着的客户端发送消息
foreach (Socket socket in serverSocketClass.AcceptSocketList)
{
serverSocketClass.ServerSendMessage(socket, message);
}
}
}
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Net;
using System.Net.Sockets;
using System.Threading;
namespace ClientSocket
{
//接收,监听,发送消息的类,自己创建
public class StateObject
{
public Socket socket = null;
public byte[] buffer = new byte[128];
public int offset = 0;
public StateObject() { }
}
public class ClientSocketClass
{
//单利
public static ClientSocketClass instance = null;
//用于存放所有的线程
public List<Thread> threadList = new List<Thread>();
//用于存放连接的服务端
public List<Socket> socketList = new List<Socket>();
public Socket clientSocket;
//创建一个单利方法
public static ClientSocketClass Init()
{
if (instance == null)
{
instance = new ClientSocketClass();
}
return instance;
}
public ClientSocketClass()
{
//端口号
int port = 11111;
//IP地址
IPAddress ipAddress = IPAddress.Parse("127.0.0.1");
IPEndPoint ipEndPoint = new IPEndPoint(ipAddress, port);
clientSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
try
{
StateObject stateObject = new StateObject();
stateObject.socket = clientSocket;
clientSocket.BeginConnect(ipEndPoint, new AsyncCallback(ConnectCallBack), stateObject);
}
catch
{ }
}
//异步连接的回调方法
public void ConnectCallBack(IAsyncResult connect)
{
StateObject stateObject = (StateObject)connect.AsyncState;
Socket clientSocket = stateObject.socket;
Console.WriteLine("成功连接服务器,本地 : {0}; 服务器 {1}; 可以发消息啦", clientSocket.LocalEndPoint, clientSocket.RemoteEndPoint);
try
{
clientSocket.EndConnect(connect);
}
catch { }
//将连接到的服务端存放进集合
socketList.Add(clientSocket);
}
//创建接收消息的线程
public void CreateThreadReceive(Socket clientSocket)
{
//开启一个接收消息的线程
ParameterizedThreadStart threadStart = new ParameterizedThreadStart(SocketBeginReceive);
Thread thread = new Thread(threadStart);
thread.IsBackground = true;
thread.Start(clientSocket);
threadList.Add(thread);
}
//发送消息的方法
public void ClientSendMessage( Socket client, string message)
{
StateObject stateObject = new StateObject();
stateObject.socket = client;
try
{
stateObject.buffer = Encoding.UTF8.GetBytes(message);
//开启异步发送消息
client.BeginSend(stateObject.buffer, 0, stateObject.buffer.Length, 0, new AsyncCallback(SendMessageCallBack), stateObject);
}
catch (Exception e){
Console.WriteLine("ddd {0}", e);
CloseSocket(client);
}
}
//发送消息的回调方法
public void SendMessageCallBack(IAsyncResult send)
{
StateObject stateObject = (StateObject)send.AsyncState;
Socket client = stateObject.socket;
//int count = client.EndSend(send);//获取发送消息的长度
//获取发送的消息, 转换为字符串
//string str = new ASCIIEncoding().GetString(stateObject.buffer);
//在控制台打印
//Console.WriteLine("客户端:发送消息长度{0}: 内容{1}", count.ToString(), new ASCIIEncoding().GetString( stateObject.buffer));
}
//调用该方法发送消息, 参数为要发送的 Socket对象
public void SocketBeginReceive(object s)
{
Socket socket = (Socket)s;
StateObject stateObject = new StateObject();
stateObject.socket = socket;
try
{
while (true)
{
//异步接收客户端发来的信息
socket.BeginReceive(stateObject.buffer, 0, stateObject.buffer.Length, 0, new AsyncCallback(ReceiveCallBack), stateObject);
Thread.Sleep(100);
}
}
catch { CloseSocket(socket); }
}
//接收消息的回调方法
public void ReceiveCallBack(IAsyncResult receive)
{
StateObject stateObject = (StateObject)receive.AsyncState;
Socket s = stateObject.socket;
//接收消息的回调方法要调用 EndReceive() 方法
int read = s.EndReceive(receive);
if (read > 0)
{
try
{
ASCIIEncoding encoding = new ASCIIEncoding();
string str = encoding.GetString(stateObject.buffer);
Console.WriteLine("服务端 :{0}", str);// 输出服务端发来的消息
s.BeginReceive(stateObject.buffer, 0, stateObject.buffer.Length, 0, new AsyncCallback(ReceiveCallBack), stateObject);
}
catch { }
}
else
{
CloseSocket(s);
}
}
//销毁线程
public void CloseThread()
{
foreach (Thread thread in threadList)
{
if (thread.IsAlive)
{
thread.Abort();
}
}
}
//断开Socket
public void CloseSocket(Socket s)
{
if (!s.Connected)
{
s.Shutdown(SocketShutdown.Both);
s.Close();
}
}
}
class Program
{
static void Main(string[] args)
{
ClientSocketClass clientSocketClass = ClientSocketClass.Init();
//开始接收
StartReceive( clientSocketClass);
string str = "";
while (true)
{
str = Console.ReadLine();//输入要发送的消息
//向服务器发送消息
clientSocketClass.ClientSendMessage(clientSocketClass.clientSocket, str);
Thread.Sleep(100);
}
}
//开始接收消息
public static void StartReceive(ClientSocketClass clientSocketCla)
{
ClientSocketClass clientSocketClass = clientSocketCla;
while (true)
{
//为了能够监听连接的服务端发来的消息,在没有连接到服务端时一直调用
if (clientSocketClass.socketList.Count > 0)
{
foreach (Socket socket in clientSocketClass.socketList)
{
clientSocketClass.CreateThreadReceive(socket);
}
//当连接到服务端时,退出循环
break;
}
}
}
}
}
创建两个项目,一个粘贴服务端代码,一个粘贴客户端代码
(1)运行服务端项目,结果如下
(2)运行客户端,如下图
(3)接下来就可以相互发送消息啦