using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.IO;
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 SocketServer
{
public partial class Form1 : Form
{
public static Socket ServerSocket; //监听的套接字
public static Socket SocketAccept; //绑定客户端套接字
public static Socket socket; //用于某一个客户端通信的套接字
public static int SFlag = 0; //连接成功标志
public static int CFlag = 0; //客户端关闭标志
Thread th1; //线程1
Thread th2; //线程2
public Form1()
{
InitializeComponent();
btn_Close.Enabled = false;
}
private void Form1_Load(object sender, EventArgs e)
{
//执行新线程时跨线程资源访问检查会提示报错,这里关闭
Control.CheckForIllegalCrossThreadCalls = false;
}
private void btn_Receive_Click(object sender, EventArgs e)
{
//1.创建一个用于监听连接的Socket对象
ServerSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
rtb_Receive.Text += "服务器已打开,正在等待连接...\n";
btn_Receive.Enabled = false;
btn_Close.Enabled = true;
//2.用指定的端口号和服务器的ip建立一个IPEndPoint对象
IPAddress IP = IPAddress.Parse(tb_Addr.Text); //获取输入的IP地址
int Port = int.Parse(tb_Port.Text); //获取输入的端口号
IPEndPoint iPEndPoint = new IPEndPoint(IPAddress.Any, Port);
try
{
//3.用Soeket对象Bind方法绑定IPEndPoint
ServerSocket.Bind(iPEndPoint);
//4.用Soeket对象Listen方法开始监听
ServerSocket.Listen(10);
//开启线程Accept进行通信的客户端socket
th1 = new Thread(Listen); //线程绑定Listen
th1.IsBackground = true; //在后台执行线程
th1.Start(ServerSocket); //Start里面的参数是函数Listen函数所需要的参数,用于通讯的socket对象
Console.WriteLine("1");
}
catch
{
MessageBox.Show("服务器出问题了!");
}
}
void Listen(Object sk)
{
SocketAccept = sk as Socket; //创建一个与客户端对接的套接字
try
{
while(true)
{
//5.建立与客户端的连接,用socket对象Accept方法创建用户和客户端进行通信的socket对象
socket = SocketAccept.Accept();
CFlag = 0;
SFlag = 1;
rtb_Receive.Text += DateTime.Now.ToString("yy-MM-dd hh:mm:ss ") + tb_Addr.Text + " 连接成功";
rtb_Receive.Text += "\r\n";
th2 = new Thread(Receive);
th2.IsBackground = true;
th2.Start(socket);
}
}
catch
{
}
}
void Receive(Object sk)
{
socket = sk as Socket;
while(true)
{
try
{
if(CFlag == 0 && SFlag == 1)
{
//6.接收来自客户端的信息
byte[] receive = new byte[1024];
int len = socket.Receive(receive);
if(receive.Length > 0)
{
if (Encoding.UTF8.GetString(receive, 0,len) == "*close")
{
rtb_Receive.Text += DateTime.Now.ToString("yy-MM-dd hh:mm:ss ") + "客户端已退出" + "\n";
CFlag = 1;
break;
}
rtb_Receive.Text += DateTime.Now.ToString("yy-MM-dd hh:mm:ss ") + "来自用户的消息: ";
rtb_Receive.Text += Encoding.UTF8.GetString(receive);
rtb_Receive.Text += "\r\n";
}
}
else
{
break;
}
}
catch
{
MessageBox.Show("接收不到消息");
}
}
}
private byte[] SendData(byte[] reveice)
{
MemoryStream memoryStream = new MemoryStream(); //创建内存流
byte[] bagHead = BitConverter.GetBytes(reveice.Length + 4);
memoryStream.Write(bagHead, 0, bagHead.Length);
memoryStream.Write(reveice, 0, reveice.Length);
byte[] headAndBody = memoryStream.ToArray();
memoryStream.Close();
memoryStream.Dispose();
return headAndBody;
}
private void btn_Send_Click(object sender, EventArgs e)
{
if(SFlag == 1 && CFlag == 0)
{
//7.向客户端发送消息
byte[] send = new byte[1024];
send = Encoding.UTF8.GetBytes(rtb_Send.Text);
//var headAndBody = SendData(send);
socket.Send(send);
rtb_Receive.Text += DateTime.Now.ToString("yy-MM-ss hh:mm:ss ") + "发送:";
rtb_Receive.Text += rtb_Send.Text + "\n";
rtb_Send.Clear();
}
}
private void btn_Close_Click(object sender, EventArgs e)
{
if(CFlag == 1)
{
th2.Abort();
socket.Close();
}
//8.关闭Socket
ServerSocket.Close();
SocketAccept.Close();
th1.Abort();
CFlag = 0;
SFlag = 0;
btn_Receive.Enabled = true;
btn_Close.Enabled = false;
rtb_Receive.Text += DateTime.Now.ToString("yy-MM_dd hh:mm:ss ");
rtb_Receive.Text += "服务器已关闭" + "\n";
}
private void rtb_Send_KeyDown(object sender, KeyEventArgs e)
{
if(e.KeyCode == Keys.Enter)
{
this.btn_Send_Click(sender, e);
}
}
private void btn_ClearScreen_Click(object sender, EventArgs e)
{
rtb_Receive.Clear();
}
}
}
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.IO;
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 SocketClient
{
public partial class Form1 : Form
{
public static Socket ClientSocket;
public static Socket socket;
public static int SFlag = 0;
Thread th1;
public Form1()
{
InitializeComponent();
btn_Close.Enabled = false;
}
private void Form1_Load(object sender, EventArgs e)
{
Control.CheckForIllegalCrossThreadCalls = false;
}
private void btn_Connect_Click(object sender, EventArgs e)
{
ClientSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
rtb_Receive.Text += "正在连接服务器...\n";
IPAddress IP = IPAddress.Parse(tb_Addr.Text);
int Port = int.Parse(tb_Port.Text);
IPEndPoint iPEndPoint = new IPEndPoint(IP, Port);
try
{
ClientSocket.Connect(iPEndPoint);
SFlag = 1;
rtb_Receive.Text += DateTime.Now.ToString("yy-MM-dd hh:mm:ss ") + tb_Addr.Text + " 连接成功" + "\n";
btn_Connect.Enabled = false;
btn_Close.Enabled = true;
th1 = new Thread(Receive);
th1.IsBackground = true;
th1.Start(ClientSocket);
}
catch
{
rtb_Receive.Text += DateTime.Now.ToString("yy-MM-dd hh:mm:ss ") + tb_Addr.Text + " 服务器未打开!" + "\n";
btn_Connect.Enabled = true;
}
}
//MemoryStream memoryStream = new MemoryStream(); //创建内存流
void Receive(object sk)
{
//socket = sk as Socket;
while (true)
{
byte[] receive = new byte[1024];
ClientSocket.Receive(receive);
//int len = socket.Receive(receive);
//int receiveLength = 1024;
//memoryStream.Write(reveive, 0, receiveLength); //将接收到的数据写入内存流中
//byte[] getData = memoryStream.ToArray(); //将内存流中的消息体写入字节数组
//int startIndex = 0; //读取数据的起始下标
if (receive.Length > 0) //如果接收到的消息长度大于0
{
//int headLength; //包头和包体长度
//if (getData.Length - startIndex < 4) //包头接收不完整
//{
// headLength = -1;
//}
//else
//{
// //包头接收完整,转为int类型的数值
// headLength = BitConverter.ToInt32(getData, startIndex);
//}
包头完整但是消息体不完整 或者 包头接收不完整
//if (getData.Length - startIndex < headLength || headLength == 1)
//{
// memoryStream.Close(); //关闭内存
// memoryStream.Dispose(); //释放资源
// memoryStream = new MemoryStream(); //创建新的内存流
// //重新将接收的消息写入内存流
// memoryStream.Write(getData, startIndex, getData.Length - startIndex);
// break;
//}
//else
//{
//if (Encoding.UTF8.GetString(receive, 0, len) == "*close")
//{
// rtb_Receive.Text += DateTime.Now.ToString("yy-MM-dd hh:mm:ss ") + "服务器已退出" + "\n";
// //CFlag = 1;
// break;
//}
//如果包头和消息体都接收完整了,就解析数据并显示
rtb_Receive.Text += DateTime.Now.ToString("yy-MM-ss hh:mm:ss ") + "来自服务器的消息:";
//rtb_Receive.Text += Encoding.UTF8.GetString(getData,startIndex + 4,headLength - 4);
rtb_Receive.Text += Encoding.UTF8.GetString(receive);
rtb_Receive.Text += "\r\n";
//}
}
}
}
private byte[] SendData(byte[] reveice)
{
MemoryStream memoryStream = new MemoryStream(); //创建内存流
//往字节数组中写入包头自身和消息体的长度
byte[] bagHead = BitConverter.GetBytes(reveice.Length + 4);
memoryStream.Write(bagHead, 0, bagHead.Length); //包头写入内存流
memoryStream.Write(reveice, 0, reveice.Length); //消息体写入内存流
byte[] headAndBody = memoryStream.ToArray(); //内存流中的数据写入字节数组
memoryStream.Close(); //关闭内存流
memoryStream.Dispose(); //释放资源
return headAndBody; //返回字节数组
}
private void btn_Send_Click(object sender, EventArgs e)
{
if(SFlag == 1)
{
byte[] send = new byte[1024];
send = Encoding.UTF8.GetBytes(rtb_Send.Text);
//var headAndBody = SendData(send); //将数据转为内存流
ClientSocket.Send(send);
rtb_Receive.Text += DateTime.Now.ToString("yy-MM-ss hh:mm:ss ") + "发送: ";
rtb_Receive.Text += rtb_Send.Text + "\n";
rtb_Send.Clear();
}
else
{
rtb_Receive.Text += "服务器未打开,无法发送消息!\n";
}
}
private void btn_Close_Click(object sender, EventArgs e)
{
if(SFlag == 1)
{
byte[] send = new byte[1024];
send = Encoding.ASCII.GetBytes("*close");
ClientSocket.Send(send);
th1.Abort();
ClientSocket.Close();
btn_Close.Enabled = false;
btn_Connect.Enabled = true;
SFlag = 0;
rtb_Receive.Text += DateTime.Now.ToString("yy-MM-ss hh:mm:ss ");
rtb_Receive.Text += "客户端已关闭" + "\n";
}
}
private void rtb_Send_KeyDown(object sender, KeyEventArgs e)
{
if(e.KeyCode == Keys.Enter)
{
this.btn_Send_Click(sender, e);
}
}
private void btn_ClearScreen_Click(object sender, EventArgs e)
{
rtb_Receive.Clear();
}
}
}
单纯记录,万一以后要用呢