阻塞式聊天程序客户端服务端
服务端代码:
新客户端.NoDelay = true;//不延迟,应该为true时表示立即发送数据。缓冲区未满时禁用延迟
namespace 同步套接字编程
{
public partial class Form1 : Form
{
Socket 套接字;
Socket 新套接字;
Thread 线程;
public Form1()
{
InitializeComponent();
Control.CheckForIllegalCrossThreadCalls = false;
}
private void 开始监听bt_Click(object sender, EventArgs e)
{
IPAddress ip = IPAddress.Parse(tex服务器IP.Text);
IPEndPoint ip终端 = new IPEndPoint(ip, int.Parse(tex监听端口.Text));
套接字 = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
套接字.Bind(ip终端);
//开始监听
套接字.Listen(10);//最大连接请求
新套接字 = 套接字.Accept();
listBox1.Items.Add("与客户" + 新套接字.RemoteEndPoint.ToString() + "建立连接");
线程 = new Thread(new ThreadStart(接收消息));
线程.Start();
}
void 接收消息()
{
while(true)
{
try
{
NetworkStream netStream = new NetworkStream(新套接字);//用于接收新套接字的 网络流
byte[] 数据尺寸 = new byte[4];
netStream.Read(数据尺寸, 0, 4);
int size = System.BitConverter.ToInt32(数据尺寸, 0);//将4字节数组转换成int. 4字节刚好是一个int
byte[] 消息 = new byte[size];//头数据里保存的是 消息有多少个byte
int 数据自身大小 = size;
int start = 0;
while(数据自身大小>0)//先读4个,头字节. 然后不断的读. 直到读完
{
int 接受长度 = netStream.Read(消息, start, 数据自身大小);
start += 接受长度;
数据自身大小 -= 接受长度;
}
tex接受信息.Rtf = System.Text.Encoding.Unicode.GetString(消息);
}
catch(Exception a)
{
listBox1.Items.Add("与客户断开连接");
break;
}
}
}
private void 发送信息bt_Click(object sender, EventArgs e)
{
string str = tex发送信息.Rtf;
int 信息长度 = str.Length;
if (信息长度== 0)
return;
else
信息长度 *= 2;//string每个leng占2个byte
byte[] 数据尺寸 = new byte[4];
数据尺寸 = System.BitConverter.GetBytes(信息长度);
byte[] 发送的数据 = System.Text.Encoding.Unicode.GetBytes(str);
try
{
NetworkStream netStream = new NetworkStream(新套接字);
netStream.Write(数据尺寸, 0, 4);//将数据尺寸先发送
netStream.Write(发送的数据, 0, 发送的数据.Length);
netStream.Flush();
tex发送信息.Rtf = "";
}
catch(Exception a)
{
MessageBox.Show("无法发送");
}
}
private void 停止监听bt_Click(object sender, EventArgs e)
{
try
{
套接字.Shutdown(SocketShutdown.Both);
套接字.Close();
if(新套接字.Connected)
{
新套接字.Close();
线程.Abort();
}
}
catch(Exception a)
{
}
}
}
}
客户端
namespace TCP协议_客户端
{
public partial class Form1 : Form
{
Socket 套接字;
Thread 线程;
public Form1()
{
InitializeComponent();
CheckForIllegalCrossThreadCalls = false;
}
private void listBox1_SelectedIndexChanged(object sender, EventArgs e)
{
}
private void 连接到主机bt_Click(object sender, EventArgs e)
{
IPAddress 目标ip = IPAddress.Parse(tex服务器.Text);
IPEndPoint 目标ip终端 = new IPEndPoint(目标ip, int.Parse(tex目标端口.Text));
套接字 = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
try
{
套接字.Connect(目标ip终端);
}
catch(Exception a)
{
MessageBox.Show("与服务器连接失败!");
return;
}
listBox1.Items.Add("与服务器连接成功");
Thread thread = new Thread(接受信息);
thread.Start();
}
private void 发送信息bt_Click(object sender, EventArgs e)
{
string str = tex发送信息.Rtf;
int i = str.Length;
if (i == 0)
return;
else
i *= 2;
byte[] 数据头 = new byte[4];
数据头 = System.BitConverter.GetBytes(i);
byte[] 发送数据s = System.Text.Encoding.Unicode.GetBytes(str);
try
{
NetworkStream netStream = new NetworkStream(套接字);
netStream.Write(数据头, 0, 4);
netStream.Write(发送数据s, 0, 发送数据s.Length);
netStream.Flush();
tex发送信息.Rtf = "";
}
catch(Exception a)
{
MessageBox.Show("无法发送!");
}
}
void 接受信息()
{
while(true)
{
try
{
NetworkStream netStream = new NetworkStream(套接字);
byte[] 数据尺寸 = new byte[4];
netStream.Read(数据尺寸, 0, 4);
int 接受数据尺寸 = System.BitConverter.ToInt32(数据尺寸, 0);
byte[] 消息 = new byte[接受数据尺寸];
int 剩余数据尺寸 = 接受数据尺寸;
int 接受数据起时位置 = 0;
while(剩余数据尺寸>0)
{
int 已接受 = netStream.Read(消息, 接受数据起时位置, 剩余数据尺寸);//第二个参数的offset是指 缓存 的偏移!
接受数据起时位置 += 已接受;
剩余数据尺寸 -= 已接受;
}
tex接受信息.Rtf = System.Text.Encoding.Unicode.GetString(消息);
}
catch(Exception a)
{
listBox1.Items.Add("服务器断开连接.");
break;
}
}
}
private void 关闭连接bt_Click(object sender, EventArgs e)
{
try
{
套接字.Shutdown(SocketShutdown.Both);
套接字.Close();
listBox1.Items.Add("与主机断开连接");
线程.Abort();
}
catch(Exception a)
{
MessageBox.Show("尚未与主机连接,断开无效!");
}
}
}
}
网友评论