利用Socket类实现了本机之间的客户端与服务端的信息交互。
服务器:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace TcpSocketServer
{
public partial class TcpSocketServerForm : Form
{
IPAddress localIp;
private const int localPort =50000;
//声明一个用来发送的Socket
private Socket socketSend;
//创建一个用来存放ip地址和端口号的键值对集合
private Dictionary<string, Socket> dicSocket = new Dictionary<string, Socket>();
public TcpSocketServerForm()
{
InitializeComponent();
//获取本机IP地址
IPAddress[] ip = Dns.GetHostAddresses(Dns.GetHostName());
localIp = ip[ip.Length - 1];
//将IP地址、端口号传入到界面显示
txtServerIp.Text = localIp.ToString();
txtServerPort.Text = localPort.ToString();
txtServerIp.Enabled = false;
txtServerPort.Enabled = false;
}
private void TcpSocketServerForm_Load(object sender, EventArgs e)
{
// Control.CheckForIllegalCrossThreadCalls = false;
}
//开启监听
private void btnStartListen_Click(object sender, EventArgs e)
{
//创建一个负责监听远程连接IP地址和端口号的Socket
Socket socketListen = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
//监听远程的IP地址设为任意
IPAddress ip = IPAddress.Any;
//获得端口号对象
IPEndPoint iep = new IPEndPoint(ip, localPort);
//将端口号绑定到监听的Socket上
socketListen.Bind(iep);
//设置监听队列d
socketListen.Listen(10);
//将消息显示在前端
AddMsgToTxtLog(localIp.ToString() + " " + localPort.ToString() + ":监听成功");
//ShowMsg("监听成功");
//开启一个线程执行监听程序
Thread listenThread = new Thread(Listen);
listenThread.IsBackground = true;
listenThread.Start(socketListen);
}
//监听客户端的连接,并创建与之通信的Socket
private void Listen(object o)
{
Socket socketListen = o as Socket;
while(true)
{
try
{
//通过Accept方法创建负责和客户端通信的Socket
socketSend = socketListen.Accept();
//将远程客户端的IP地址和端口号存储到ComboBox中
cboUser.Items.Add(socketSend.RemoteEndPoint.ToString());
//再将该信息及对应的Socket存入键值对集合
dicSocket.Add(socketSend.RemoteEndPoint.ToString(), socketSend);
//将信息显示到前端
AddMsgToTxtLog(socketSend.RemoteEndPoint.ToString() + "连接成功");
//ShowMsg("连接成功");
//开启一个线程不停接收客户端发来的消息
Thread receiveThread = new Thread(ReceiveData);
receiveThread.IsBackground = true;
receiveThread.Start(socketSend);
}
catch
{
}
}
}
//不停接收客户端发来的消息
private void ReceiveData(object o)
{
Socket socketSend = o as Socket;
while(true)
{
try
{
//创建接收客户端发送数据的缓冲区
byte[] buffer = new byte[1024 * 1024 * 2];
//服务器实际收到的有效字节数
int r = socketSend.Receive(buffer);
//当接收不到数据,退出
if(r ==0)
{
break;
}
//将有小子结束转换为字符串
string recSendStr = System.Text.Encoding.UTF8.GetString(buffer, 0, r);
AddMsgToTxtLog(socketSend.RemoteEndPoint.ToString() + ":" + recSendStr);
//ShowMsg(recSendStr);
}
catch
{
}
}
}
private delegate void AddMsgToText(string text);
void AddMsgToTxtLog(string str)
{
//判断是否属于跨线程调用
if(txtLog.InvokeRequired)
{
AddMsgToText d = new AddMsgToText(AddMsgToTxtLog);
txtLog.Invoke(d, DateTime.Now.ToLocalTime().ToString("yyyy-MM-dd hh:mm:ss.fff") + ":" + str);
}
else
{
txtLog.AppendText(DateTime.Now.ToLocalTime().ToString("yyyy-MM-dd hh:mm:ss.fff") + ":"+str);
}
}
//发送数据
private void btnSendMsg_Click(object sender, EventArgs e)
{
byte[] buffer = System.Text.Encoding.UTF8.GetBytes(txtSendMsg.Text);
List<byte> list = new List<byte>();
list.Add(0);
list.AddRange(buffer);
//将集合转换为数组
byte[] newBuffer = list.ToArray();
//获得下拉框选中的地址
string iep = cboUser.SelectedItem.ToString();
dicSocket[iep].Send(newBuffer);
}
void ShowMsg(string str)
{
txtLog.AppendText(str + "\r\n");
}
}
}
客户端:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace TcpSocketClient
{
public partial class TcpSocketClient : Form
{
//创建一个用于和服务器通信的Socket
private Socket socket;
//创建远程的IP地址和端口号
private string remoteIpString = "192.168.1.114";
private const int remotePort = 50000;
public TcpSocketClient()
{
InitializeComponent();
txtServerIp.Text = remoteIpString;
txtServerPort.Text = remotePort.ToString();
txtServerIp.Enabled = false;
txtServerPort.Enabled = false;
}
private void TcpSocketClient_Load(object sender, EventArgs e)
{
//Control.CheckForIllegalCrossThreadCalls = false;
}
private delegate void AddMsgToText(string text);
void AddMsgToTxtLog(string str)
{
//判断是否属于跨线程调用
if (txtLog.InvokeRequired)
{
AddMsgToText d = new AddMsgToText(AddMsgToTxtLog);
txtLog.Invoke(d, DateTime.Now.ToLocalTime().ToString("yyyy-MM-dd hh:mm:ss.fff") + ":" + str);
}
else
{
txtLog.AppendText(DateTime.Now.ToLocalTime().ToString("yyyy-MM-dd hh:mm:ss.fff") + ":" + str);
}
}
//开始连接
private void btnStartConnect_Click(object sender, EventArgs e)
{
try
{
//客户端实例化一个负责和服务器通信的Socket
socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
//获得远程服务器的IP地址
IPAddress ip = IPAddress.Parse(remoteIpString);
//获得要连接的服务器的端口号
IPEndPoint iep = new IPEndPoint(ip, remotePort);
//客户端连接远程服务器
socket.Connect(iep);
//显示在前端
AddMsgToTxtLog(iep.ToString() + "连接成功");
//ShowMsg("连接远程主机成功!");
btnStartConnect.Enabled = false;
Thread receiveThread = new Thread(ReceiveData);
receiveThread.IsBackground = true;
receiveThread.Start();
}
catch
{
AddMsgToTxtLog("连接远程主机失败!");
//ShowMsg("连接远程主机失败!");
btnStartConnect.Enabled = true;
}
}
private void ReceiveData()
{
while(true)
{
try
{
//创建接受服务端发来信息的缓冲区
byte[] buffer = new byte[1024 * 1024 * 5];
int r = socket.Receive(buffer);
byte b = buffer[0];
if(b ==0)
{
string str = System.Text.Encoding.UTF8.GetString(buffer, 1, r - 1);
AddMsgToTxtLog(socket.RemoteEndPoint.ToString() + "接收的信息:" + str);
//ShowMsg(str);
}
else
{
AddMsgToTxtLog(socket.RemoteEndPoint.ToString() + "发送格式错误!!" );
//ShowMsg("发送格式错误!");
}
}
catch
{
}
}
}
//发送信息
private void btnSendMsg_Click(object sender, EventArgs e)
{
string str = txtSendMsg.Text;
byte[] buffer = System.Text.Encoding.UTF8.GetBytes(str);
socket.Send(buffer);
}
void ShowMsg(string str)
{
txtLog.AppendText(str + "\r\n");
}
}
}