/// <summary>
/// 发送消息
/// </summary>
private void GetSendMessage()
{
IPEndPoint epF = new IPEndPoint(IPAddress.Parse(this.friendChatIP.Split(':')[0]), Convert.ToInt32(this.friendChatIP.Split(':')[1]));
try
{
//将richTextBoxSend富文本中的Rtf格式文字转换为字节数组
byte[] _byte = Encoding.ASCII.GetBytes(richTextBoxSend.Rtf);
//以1024为单位判断有多少个数据包
int packetSendMessage = (int)(_byte.Length / (long)1024);
//获取剩下不够1024的字节长度
int lastPacketSendMessage = (int)(_byte.Length - (packetSendMessage * (long)1024));
byte[] buffer = Encoding.Unicode.GetBytes(string.Format("{0}{1}|{2}", Config.CHATHEAD, Config.loginId, this.userName));
//向服务器发送消息头
socketChat.SendTo(buffer, epF);
int sendLength = 0;
int intlength = 1024;
//开始遍历数据包并发送
for (int i = 0; i < packetSendMessage; i++)
{
//判断当前数据包是足够1KB
if (_byte.Length >= i * 1024 + 1024)
{
//从 _byte变量中截取1024位
string content = Encoding.ASCII.GetString(_byte, i * 1024, i * 1024 + 1024);
buffer = Encoding.ASCII.GetBytes(content);
//将数据包头转换成字节数组
byte[] temp = Encoding.Unicode.GetBytes(Config.CHATMSG);
//向服务器发送聊天消息,ToBuffer为将_byte和temp两个数据合并成一个,返回byte[]类型
socketChat.SendTo(ToBuffer(buffer, temp, buffer.Length, temp.Length), epF);
Thread.Sleep(20);
}
}
//判断是否还有剩下的数据包,有就一并发送
if (lastPacketSendMessage != 0)
{
string content = Encoding.ASCII.GetString(_byte, sendLength, lastPacketSendMessage);
buffer = Encoding.ASCII.GetBytes(content);
byte[] temp = Encoding.Unicode.GetBytes(Config.CHATLASTMSG);
//向服务器发送聊天消息
socketChat.SendTo(ToBuffer(buffer, temp, buffer.Length, temp.Length), epF);
}
//清空输入框
richTextBoxSend.Text = string.Empty;
}
catch (Exception exp)
{
byte[] buffer =new byte[0];
byte[] temp = Encoding.Unicode.GetBytes(Config.CHATLASTMSG);
//向服务器发送聊天消息
socketChat.SendTo(ToBuffer(buffer, temp, buffer.Length, temp.Length), epF);
ShowMessage(string.Format("向好友发送消息出错:" + exp.Message), MessageBoxIcon.Error);
}
}
如果发消息过多,会提示这个
"索引和计数必须引用该缓冲区内的位置,参数名:bytes"
这是什么意思呀?我调试过了,确实是没有数组越界呀。发送的文字多的话,会截取成多个片段发送,第一个片段发送成功了,第二个或后面的就不行了。就提示这个。
int packetSendMessage = (int)(_byte.Length / (long)1024);
//应该改成
int packetSendMessage = (int)(_byte.Length / (long)1024) + 1;
2. 为啥发送的时候要用SendTo? 直接Send不可以吗?建议改进。
2、因为是用的UDP发送的,而不是TCP,要是TCP就不需要人工分包了。
string content = Encoding.ASCII.GetString(_byte, i * 1024, i * 1024 + 1024);
第三个参数应该是1024,而不是i * 1024 + 1024,它代表要发送的字节数,而不是结束位置。另外你没必要这么麻烦,这样写就可以了。
for (int i = 0; i < packetSendMessage; i++)
{
//判断当前数据包是足够1KB
if (_byte.Length >= i * 1024 + 1024)
{
//向服务器发送聊天消息
socketChat.SendTo(_byte, i * 1024, 1024, SocketFlags.None, epF);
Thread.Sleep(20);
}
}