oschina上copy

This commit is contained in:
beykery
2016-09-23 16:07:46 +08:00
parent 58b7c96071
commit e41d944a08
53 changed files with 1882 additions and 331 deletions

View File

@@ -1 +1 @@
5;0;-1
5;0;6;-1

Binary file not shown.

View File

@@ -0,0 +1 @@
sceneSetups: []

View File

@@ -0,0 +1,2 @@
0000.5787632e.0000
0000.57876340.0000

View File

@@ -1,2 +1,2 @@
m_EditorVersion: 5.2.4f1
m_EditorVersion: 5.3.6f1
m_StandardAssetsVersion: 0

View File

@@ -8,7 +8,6 @@ namespace cocosocket4unity
{
public class ByteBuf
{
private int len;
private byte[] data;
private int readerIndex;
private int writerIndex;
@@ -20,8 +19,7 @@ namespace cocosocket4unity
**/
public ByteBuf (int capacity)
{
this.len = capacity;
this.data = new byte[len];
this.data = new byte[capacity];
readerIndex = 0;
writerIndex = 0;
markReader = 0;
@@ -29,19 +27,22 @@ namespace cocosocket4unity
}
public ByteBuf(byte[] content)
{
this.len = content.Length;
this.data = content;
readerIndex = 0;
writerIndex = len;
writerIndex = content.Length;
markReader = 0;
markWriter = 0;
}
private ByteBuf()
{
}
/**
* 容量
**/
public int Capacity ()
{
return len;
return data.Length;
}
/**
@@ -49,11 +50,11 @@ namespace cocosocket4unity
*/
public ByteBuf Capacity (int nc)
{
if (nc > len) {
if (nc > data.Length)
{
byte[] old = data;
data = new byte[nc];
Array.Copy (old, data, len);
len = nc;
Array.Copy (old, data, data.Length);
}
return this;
}
@@ -75,20 +76,34 @@ namespace cocosocket4unity
**/
public ByteBuf Copy()
{
ByteBuf item = new ByteBuf(len);
Array.Copy (this.data, item.data, len);
ByteBuf item = new ByteBuf(data.Length);
Array.Copy (this.data, item.data, data.Length);
item.readerIndex = readerIndex;
item.writerIndex = writerIndex;
item.markReader = markReader;
item.markWriter = markWriter;
return item;
}
/// <summary>
/// 浅拷贝
/// </summary>
/// <returns></returns>
public ByteBuf Duplicate()
{
ByteBuf item = new ByteBuf();
item.readerIndex = readerIndex;
item.writerIndex = writerIndex;
item.markReader = markReader;
item.markWriter = markWriter;
item.data = data;
return item;
}
/**
* 获取一个字节
**/
public byte GetByte(int index)
{
if (index < len)
if (index < data.Length)
{
return data[index];
}
@@ -99,7 +114,7 @@ namespace cocosocket4unity
**/
public int GetInt(int index)
{
if (index + 3 < len)
if (index + 3 < data.Length)
{
int ret = ((int) data[index]) << 24;
ret |= ((int) data[index + 1]) << 16;
@@ -114,7 +129,7 @@ namespace cocosocket4unity
**/
public short GetShort(int index)
{
if (index + 1 < len)
if (index + 1 < data.Length)
{
short r1 = (short)(data[index] << 8);
short r2 = (short)(data[index + 1]);
@@ -144,7 +159,7 @@ namespace cocosocket4unity
**/
public int MaxWritableBytes()
{
return len - writerIndex;
return data.Length - writerIndex;
}
/**
* 读取一个字节
@@ -165,14 +180,11 @@ namespace cocosocket4unity
{
if (readerIndex + 3 < writerIndex)
{
unchecked
{
int ret = (int)(((data [readerIndex++]) << 24) & 0xff000000);
ret |= (((data [readerIndex++]) << 16) & 0x00ff0000);
ret |= (((data [readerIndex++]) << 8) & 0x0000ff00);
ret |= (((data [readerIndex++])) & 0x000000ff);
return ret;
}
}
return 0;
}
@@ -242,7 +254,7 @@ namespace cocosocket4unity
**/
public ByteBuf SetByte(int index, byte value)
{
if (index < len)
if (index < data.Length)
{
data[index] = value;
}
@@ -266,7 +278,7 @@ namespace cocosocket4unity
**/
public ByteBuf SetIndex(int readerIndex, int writerIndex)
{
if (readerIndex >= 0 && readerIndex <= writerIndex && writerIndex <= len)
if (readerIndex >= 0 && readerIndex <= writerIndex && writerIndex <= data.Length)
{
this.readerIndex = readerIndex;
this.writerIndex = writerIndex;
@@ -278,7 +290,7 @@ namespace cocosocket4unity
**/
public ByteBuf SetInt(int index, int value)
{
if (index + 4 <= len)
if (index + 4 <= data.Length)
{
data[index++] = (byte)((value >> 24) & 0xff);
data[index++] = (byte)((value >> 16) & 0xff);
@@ -292,7 +304,7 @@ namespace cocosocket4unity
**/
public ByteBuf SetShort(int index, short value)
{
if (index + 2 <= len)
if (index + 2 <= data.Length)
{
data[index++] = (byte)((value >> 8) & 0xff);
data[index++] = (byte)(value & 0xff);
@@ -315,7 +327,7 @@ namespace cocosocket4unity
**/
public int WritableBytes()
{
return len - writerIndex;
return data.Length - writerIndex;
}
/**
* 写入一个字节
@@ -444,7 +456,7 @@ namespace cocosocket4unity
**/
public ByteBuf WriterIndex(int writerIndex)
{
if (writerIndex >= readerIndex && writerIndex <= len)
if (writerIndex >= readerIndex && writerIndex <= data.Length)
{
this.writerIndex = writerIndex;
}
@@ -459,11 +471,6 @@ namespace cocosocket4unity
}
}
}

View File

@@ -75,6 +75,7 @@ public class Kcp
private ByteBuf buffer;
private int fastresend;
private int nocwnd;
private bool stream;
private int logmask;
private Output output;
private Object user;
@@ -96,22 +97,25 @@ public class Kcp
class Segment
{
public int conv = 0;
public byte cmd = 0;
public int frg = 0;
public int wnd = 0;
public int ts = 0;
public int sn = 0;
public int una = 0;
public int resendts = 0;
public int rto = 0;
public int fastack = 0;
public int xmit = 0;
public ByteBuf data;
public int conv = 0;
public byte cmd = 0;
public int frg = 0;
public int wnd = 0;
public int ts = 0;
public int sn = 0;
public int una = 0;
public int resendts = 0;
public int rto = 0;
public int fastack = 0;
public int xmit = 0;
public ByteBuf data;
public Segment(int size)
{
this.data = new ByteBuf(size);
if (size > 0)
{
this.data = new ByteBuf(size);
}
}
/**
@@ -131,7 +135,7 @@ public class Kcp
buf.WriteInt(ts);
buf.WriteInt(sn);
buf.WriteInt(una);
buf.WriteInt(data.ReadableBytes());
buf.WriteInt(data == null ? 0 : data.ReadableBytes());
return buf.WriterIndex() - off;
}
}
@@ -153,10 +157,11 @@ public class Kcp
mss = mtu - IKCP_OVERHEAD;
rx_rto = IKCP_RTO_DEF;
rx_minrto = IKCP_RTO_MIN;
this.interval = IKCP_INTERVAL;
interval = IKCP_INTERVAL;
ts_flush = IKCP_INTERVAL;
ssthresh = IKCP_THRESH_INIT;
dead_link = IKCP_DEADLINK;
rcv_nxt = 0;
buffer = new ByteBuf((mtu + IKCP_OVERHEAD) * 3);
this.output = output;
this.user = user;
@@ -174,7 +179,7 @@ public class Kcp
return -1;
}
Segment seq = rcv_queue.First();
if (0 == seq.frg)
if (seq.frg == 0)
{
return seq.data.ReadableBytes();
}
@@ -187,7 +192,7 @@ public class Kcp
{
Segment item = rcv_queue[i];
length += item.data.ReadableBytes();
if (0 == item.frg)
if (item.frg == 0)
{
break;
}
@@ -208,42 +213,33 @@ public class Kcp
return -1;
}
int peekSize = PeekSize();
if (0 > peekSize)
if (peekSize < 0)
{
return -2;
}
if (peekSize > buffer.WritableBytes())
{
return -3;
}
bool fast_recover = false;
if (rcv_queue.Count >= rcv_wnd)
{
fast_recover = true;
}
bool recover = rcv_queue.Count >= rcv_wnd;
// merge fragment.
int count = 0;
int n = 0;
for(int i=0;i<rcv_queue.Count;i++)
int c = 0;
int len = 0;
for (int i=0;i<rcv_queue.Count;i++ )
{
Segment seg=rcv_queue[i];
n += seg.data.ReadableBytes();
len += seg.data.ReadableBytes();
buffer.WriteBytes(seg.data);
count++;
if (0 == seg.frg)
c++;
if (seg.frg == 0)
{
break;
}
}
if (0 < count)
if(c>0)
rcv_queue.RemoveRange(0,c);
if (len != peekSize)
{
for (int i = 0; i < count; i++)
{
rcv_queue.RemoveAt(0);
}
throw new Exception("数据异常.");
}
// move available data from rcv_buf -> rcv_queue
count = 0;
c = 0;
for (int i = 0; i < rcv_buf.Count;i++ )
{
Segment seg = rcv_buf[i];
@@ -251,28 +247,23 @@ public class Kcp
{
rcv_queue.Add(seg);
rcv_nxt++;
count++;
c++;
}
else
{
break;
}
}
if (0 < count)
{
for (int i = 0; i < count; i++)
{
rcv_buf.RemoveAt(0);
}
}
if(c>0)
rcv_buf.RemoveRange(0, c);
// fast recover
if (rcv_queue.Count < rcv_wnd && fast_recover)
if (rcv_queue.Count < rcv_wnd && recover)
{
// ready to send back IKCP_CMD_WINS in ikcp_flush
// tell remote my window size
probe |= IKCP_ASK_TELL;
}
return n;
return len;
}
/**
@@ -283,39 +274,48 @@ public class Kcp
*/
public int Send(ByteBuf buffer)
{
if (0 == buffer.ReadableBytes())
if (buffer.ReadableBytes()==0)
{
return -1;
}
// append to previous segment in streaming mode (if possible)
if (this.stream && this.snd_queue.Count>0)
{
Segment seg = snd_queue.Last();
if (seg.data != null && seg.data.ReadableBytes() < mss)
{
int capacity = mss - seg.data.ReadableBytes();
int extend = (buffer.ReadableBytes() < capacity) ? buffer.ReadableBytes() : capacity;
seg.data.WriteBytes(buffer, extend);
if (buffer.ReadableBytes() == 0)
{
return 0;
}
}
}
int count;
if (buffer.ReadableBytes() < mss)
if (buffer.ReadableBytes() <= mss)
{
count = 1;
} else
{
count = (buffer.ReadableBytes() + mss - 1) / mss;
}
if (255 < count)
if (count > 255)
{
return -2;
}
if (0 == count)
if (count == 0)
{
count = 1;
}
//fragment
for (int i = 0; i < count; i++)
{
int size;
if (buffer.ReadableBytes() > mss)
{
size = mss;
} else
{
size = buffer.ReadableBytes();
}
int size = buffer.ReadableBytes() > mss ? mss : buffer.ReadableBytes();
Segment seg = new Segment(size);
seg.data.WriteBytes(buffer, size);
seg.frg = count - i - 1;
seg.frg = this.stream?0:count - i - 1;
snd_queue.Add(seg);
}
return 0;
@@ -326,16 +326,16 @@ public class Kcp
*
* @param rtt
*/
private void update_ack(int rtt)
private void Update_ack(int rtt)
{
if (0 == rx_srtt)
if (rx_srtt == 0)
{
rx_srtt = rtt;
rx_rttval = rtt / 2;
} else
{
int delta = rtt - rx_srtt;
if (0 > delta)
if (delta < 0)
{
delta = -delta;
}
@@ -350,70 +350,90 @@ public class Kcp
rx_rto = _ibound_(rx_minrto, rto, IKCP_RTO_MAX);
}
private void shrink_buf()
private void Shrink_buf()
{
if (snd_buf.Count > 0)
{
snd_una = snd_buf[0].sn;
snd_una = snd_buf.First().sn;
} else
{
snd_una = snd_nxt;
}
}
private void parse_ack(int sn)
private void Parse_ack(int sn)
{
if (_itimediff(sn, snd_una) < 0 || _itimediff(sn, snd_nxt) >= 0)
{
return;
}
int index = 0;
for (int i = 0; i < snd_buf.Count; i++)
{
Segment seg = snd_buf[i];
if (sn == seg.sn)
{
snd_buf.RemoveAt(index);
snd_buf.RemoveAt(i);
break;
}
if (_itimediff(sn, seg.sn) < 0)
{
break;
} else
{
seg.fastack++;
}
index++;
}
}
private void parse_una(int una)
private void Parse_una(int una)
{
int count = 0;
int c = 0;
for (int i = 0; i < snd_buf.Count;i++ )
{
Segment seg = snd_buf[i];
if (_itimediff(una, seg.sn) > 0)
{
count++;
c++;
}
else
{
break;
}
}
if (0 < count)
if(c>0)
snd_buf.RemoveRange(0,c);
}
private void Parse_fastack(int sn)
{
if (_itimediff(sn, snd_una) < 0 || _itimediff(sn, snd_nxt) >= 0)
{
for (int i = 0; i < count; i++)
{
snd_buf.RemoveAt(0);
}
return;
}
for (int i = 0; i < snd_buf.Count;i++ )
{
Segment seg = snd_buf[i];
if (_itimediff(sn, seg.sn) < 0)
{
break;
}
else if (sn != seg.sn)
{
seg.fastack++;
}
}
}
private void ack_push(int sn, int ts)
/**
* ack append
*
* @param sn
* @param ts
*/
private void Ack_push(int sn, int ts)
{
acklist.Add(sn);
acklist.Add(ts);
}
private void parse_data(Segment newseg)
private void Parse_data(Segment newseg)
{
int sn = newseg.sn;
if (_itimediff(sn, rcv_nxt + rcv_wnd) >= 0 || _itimediff(sn, rcv_nxt) < 0)
@@ -421,7 +441,7 @@ public class Kcp
return;
}
int n = rcv_buf.Count - 1;
int after_idx = -1;
int temp = -1;
bool repeat = false;
for (int i = n; i >= 0; i--)
{
@@ -433,42 +453,39 @@ public class Kcp
}
if (_itimediff(sn, seg.sn) > 0)
{
after_idx = i;
temp = i;
break;
}
}
if (!repeat)
{
if (after_idx == -1)
if (temp == -1)
{
rcv_buf.Insert(0,newseg);
} else
{
rcv_buf.Insert(after_idx + 1, newseg);
rcv_buf.Insert(temp + 1, newseg);
}
}
// move available data from rcv_buf -> rcv_queue
int count = 0;
for (int i = 0; i < rcv_buf.Count; i++)
int c = 0;
for (int i = 0; i < rcv_buf.Count;i++ )
{
Segment seg = rcv_buf[i];
if (seg.sn == rcv_nxt && rcv_queue.Count < rcv_wnd)
{
rcv_queue.Add(seg);
rcv_nxt++;
count++;
c++;
}
else
{
break;
}
}
if (0 < count)
if (c>0)
{
for (int i = 0; i < count; i++)
{
rcv_buf.RemoveAt(0);
}
rcv_buf.RemoveRange(0, c);
}
}
@@ -481,17 +498,18 @@ public class Kcp
*/
public int Input(ByteBuf data)
{
int s_una = snd_una;
if (data==null||data.ReadableBytes() < IKCP_OVERHEAD)
int una_temp = snd_una;
int flag = 0, maxack = 0;
if (data == null || data.ReadableBytes() < IKCP_OVERHEAD)
{
return -1;
}
int offset = 0;
while (true)
{
bool readed = false;
int ts;
int sn;
int length;
int len;
int una;
int conv_;
int wnd;
@@ -502,26 +520,18 @@ public class Kcp
break;
}
conv_ = data.ReadInt();
offset += 4;
if (conv != conv_)
if (this.conv != conv_)
{
return -1;
}
cmd = data.ReadByte();
offset += 1;
frg = data.ReadByte();
offset += 1;
wnd = data.ReadShort();
offset += 2;
ts = data.ReadInt();
offset += 4;
sn = data.ReadInt();
offset += 4;
una = data.ReadInt();
offset += 4;
length = data.ReadInt();
offset += 4;
if (data.ReadableBytes() < length)
len = data.ReadInt();
if (data.ReadableBytes() < len)
{
return -2;
}
@@ -536,38 +546,48 @@ public class Kcp
return -3;
}
rmt_wnd = wnd & 0x0000ffff;
parse_una(una);
shrink_buf();
Parse_una(una);
Shrink_buf();
switch (cmd)
{
case IKCP_CMD_ACK:
if (_itimediff(current, ts) >= 0)
{
update_ack(_itimediff(current, ts));
Update_ack(_itimediff(current, ts));
}
Parse_ack(sn);
Shrink_buf();
if (flag == 0)
{
flag = 1;
maxack = sn;
} else if (_itimediff(sn, maxack) > 0)
{
maxack = sn;
}
parse_ack(sn);
shrink_buf();
break;
case IKCP_CMD_PUSH:
Console.WriteLine(sn);
if (_itimediff(sn, rcv_nxt + rcv_wnd) < 0)
{
ack_push(sn, ts);
if (_itimediff(sn, rcv_nxt) >= 0)
{
Segment seg = new Segment(length);
seg.conv = conv_;
seg.cmd = cmd;
seg.frg = frg & 0x000000ff;
seg.wnd = wnd;
seg.ts = ts;
seg.sn = sn;
seg.una = una;
if (length > 0)
Ack_push(sn, ts);
if (_itimediff(sn, rcv_nxt) >= 0)
{
seg.data.WriteBytes(data, length);
Segment seg = new Segment(len);
seg.conv = conv_;
seg.cmd = cmd;
seg.frg = frg & 0x000000ff;
seg.wnd = wnd;
seg.ts = ts;
seg.sn = sn;
seg.una = una;
if (len > 0)
{
seg.data.WriteBytes(data, len);
readed = true;
}
Parse_data(seg);
}
parse_data(seg);
}
}
break;
case IKCP_CMD_WASK:
@@ -575,39 +595,45 @@ public class Kcp
// tell remote my window size
probe |= IKCP_ASK_TELL;
break;
// do nothing
case IKCP_CMD_WINS:
// do nothing
break;
default:
return -3;
}
offset += length;
}
if (_itimediff(snd_una, s_una) > 0)
{
if (cwnd < rmt_wnd)
if (!readed)
{
int mss_ = mss;
if (cwnd < ssthresh)
data.SkipBytes(len);
}
}
if (flag != 0)
{
Parse_fastack(maxack);
}
if (_itimediff(snd_una, una_temp) > 0)
{
if (this.cwnd < this.rmt_wnd)
{
if (this.cwnd < this.ssthresh)
{
cwnd++;
incr += mss_;
this.cwnd++;
this.incr += mss;
} else
{
if (incr < mss_)
if (this.incr < mss)
{
incr = mss_;
this.incr = mss;
}
incr += (mss_ * mss_) / incr + (mss_ / 16);
if ((cwnd + 1) * mss_ <= incr)
this.incr += (mss * mss) / this.incr + (mss / 16);
if ((this.cwnd + 1) * mss <= this.incr)
{
cwnd++;
this.cwnd++;
}
}
if (cwnd > rmt_wnd)
if (this.cwnd > this.rmt_wnd)
{
cwnd = rmt_wnd;
incr = rmt_wnd * mss_;
this.cwnd = this.rmt_wnd;
this.incr = this.rmt_wnd * mss;
}
}
}
@@ -626,12 +652,12 @@ public class Kcp
/**
* flush pending data
*/
private void flush()
private void Flush()
{
int cur = current;
int change = 0;
int lost = 0;
if (0 == updated)
if (updated == 0)
{
return;
}
@@ -641,25 +667,23 @@ public class Kcp
seg.wnd = wnd_unused();
seg.una = rcv_nxt;
// flush acknowledges
int count = acklist.Count / 2;
int offset = 0;
for (int i = 0; i < count; i++)
int c = acklist.Count / 2;
for (int i = 0; i < c; i++)
{
if (offset + IKCP_OVERHEAD > mtu)
if (buffer.ReadableBytes() + IKCP_OVERHEAD > mtu)
{
this.output.output(buffer, this, user);
offset = 0;
buffer = new ByteBuf((mtu + IKCP_OVERHEAD) * 3);
}
seg.sn = acklist[i * 2 + 0];
seg.ts = acklist[i * 2 + 1];
offset += seg.Encode(buffer);
seg.Encode(buffer);
}
acklist.Clear();
// probe window size (if remote window size equals zero)
if (0 == rmt_wnd)
if (rmt_wnd == 0)
{
if (0 == probe_wait)
if (probe_wait == 0)
{
probe_wait = IKCP_PROBE_INIT;
ts_probe = current + probe_wait;
@@ -686,68 +710,67 @@ public class Kcp
if ((probe & IKCP_ASK_SEND) != 0)
{
seg.cmd = IKCP_CMD_WASK;
if (offset + IKCP_OVERHEAD > mtu)
if (buffer.ReadableBytes() + IKCP_OVERHEAD > mtu)
{
this.output.output(buffer, this, user);
offset = 0;
buffer = new ByteBuf((mtu + IKCP_OVERHEAD) * 3);
}
offset += seg.Encode(buffer);
seg.Encode(buffer);
}
// flush window probing commands
if ((probe & IKCP_ASK_TELL) != 0)
{
seg.cmd = IKCP_CMD_WINS;
if (buffer.ReadableBytes() + IKCP_OVERHEAD > mtu)
{
this.output.output(buffer, this, user);
buffer = new ByteBuf((mtu + IKCP_OVERHEAD) * 3);
}
seg.Encode(buffer);
}
probe = 0;
// calculate window size
int cwnd_ = Math.Min(snd_wnd, rmt_wnd);
if (0 == nocwnd)
int cwnd_temp = Math.Min(snd_wnd, rmt_wnd);
if (nocwnd == 0)
{
cwnd_ = Math.Min(cwnd, cwnd_);
cwnd_temp = Math.Min(cwnd, cwnd_temp);
}
count = 0;
for(int i=0;i<snd_queue.Count;i++)
// move data from snd_queue to snd_buf
c = 0;
for (int i=0;i<snd_queue.Count;i++)
{
if (_itimediff(snd_nxt, snd_una + cwnd_) >= 0)
Segment item=snd_queue[i];
if (_itimediff(snd_nxt, snd_una + cwnd_temp) >= 0)
{
break;
}
Segment newseg = snd_queue[i];
Segment newseg = item;
newseg.conv = conv;
newseg.cmd = IKCP_CMD_PUSH;
newseg.wnd = seg.wnd;
newseg.ts = cur;
newseg.sn = snd_nxt;
newseg.sn = snd_nxt++;
newseg.una = rcv_nxt;
newseg.resendts = cur;
newseg.rto = rx_rto;
newseg.fastack = 0;
newseg.xmit = 0;
snd_buf.Add(newseg);
snd_nxt++;
count++;
c++;
}
if (0 < count)
if (c > 0)
{
for (int i = 0; i < count; i++)
{
snd_queue.RemoveAt(0);
}
snd_queue.RemoveRange(0,c);
}
// calculate resent
int resent = fastresend;
if (fastresend <= 0)
{
resent = -1;
}
int rtomin = rx_rto >> 3;
if (nodelay != 0)
{
rtomin = 0;
}
int resent = (fastresend > 0) ? fastresend : int.MaxValue;
int rtomin = (nodelay == 0) ? (rx_rto >> 3) : 0;
// flush data segments
for(int i=0;i<snd_buf.Count;i++)
for (int i=0;i<snd_buf.Count;i++)
{
Segment segment=snd_buf[i];
bool needsend = false;
//int debug = _itimediff(cur, segment.resendts);
if (0 == segment.xmit)
if (segment.xmit == 0)
{
needsend = true;
segment.xmit++;
@@ -758,7 +781,7 @@ public class Kcp
needsend = true;
segment.xmit++;
xmit++;
if (0 == nodelay)
if (nodelay == 0)
{
segment.rto += rx_rto;
} else
@@ -781,26 +804,24 @@ public class Kcp
segment.wnd = seg.wnd;
segment.una = rcv_nxt;
int need = IKCP_OVERHEAD + segment.data.ReadableBytes();
if (offset + need >= mtu)
if (buffer.ReadableBytes() + need > mtu)
{
this.output.output(buffer, this, user);
buffer = new ByteBuf((mtu + IKCP_OVERHEAD) * 3);
offset = 0;
}
offset += segment.Encode(buffer);
segment.Encode(buffer);
if (segment.data.ReadableBytes() > 0)
{
offset += segment.data.ReadableBytes();
buffer.WriteBytes(segment.data);
buffer.WriteBytes(segment.data.Duplicate());
}
if (segment.xmit >= dead_link)
{
state = 0;
state = -1;
}
}
}
// flash remain segments
if (offset > 0)
if (buffer.ReadableBytes() > 0)
{
this.output.output(buffer, this, user);
buffer = new ByteBuf((mtu + IKCP_OVERHEAD) * 3);
@@ -843,7 +864,7 @@ public class Kcp
public void Update(long current)
{
this.current = (int) current;
if (0 == updated)
if (updated == 0)
{
updated = 1;
ts_flush = this.current;
@@ -861,7 +882,7 @@ public class Kcp
{
ts_flush = this.current + interval;
}
flush();
Flush();
}
}
@@ -879,7 +900,7 @@ public class Kcp
public int Check(long current)
{
int cur = (int) current;
if (0 == updated)
if (updated == 0)
{
return cur;
}
@@ -1039,6 +1060,26 @@ public class Kcp
{
return nextUpdate;
}
public Object GetUser()
{
return user;
}
public bool IsStream()
{
return stream;
}
public void SetStream(bool stream)
{
this.stream = stream;
}
public void SetMinRto(int min)
{
rx_minrto = min;
}
}
}

View File

@@ -3,15 +3,15 @@ using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.IO;
namespace cocosocket4unity
{
/// <summary>
/// kcp客戶端程序
/// </summary>
public class KcpClient : KcpOnUdp
public abstract class KcpClient : KcpOnUdp
{
private LinkedList<ByteBuf> sendList;
protected volatile bool running;
/// <summary>
/// 初始化kcp
@@ -19,7 +19,6 @@ namespace cocosocket4unity
/// <param name="port">监听端口</param>
public KcpClient(int port):base(port)
{
this.sendList = new LinkedList<ByteBuf>();
}
/// <summary>
/// 是否在运行状态
@@ -45,6 +44,14 @@ namespace cocosocket4unity
}
}
}
protected override void HandleException(Exception ex)
{
this.Stop();
}
protected override void HandleTimeout()
{
this.Stop();
}
/// <summary>
/// 开启线程开始工作
/// </summary>
@@ -53,7 +60,7 @@ namespace cocosocket4unity
if (!this.running)
{
this.running = true;
Thread t = new Thread(new ThreadStart(run));//启动发送线程,同步发送
Thread t = new Thread(new ThreadStart(run));//状态更新
t.IsBackground = true;
t.Start();
}
@@ -64,15 +71,6 @@ namespace cocosocket4unity
{
DateTime st = DateTime.Now;
this.Update();
lock (this.sendList)
{
while(this.sendList.Count>0)
{
ByteBuf bb=this.sendList.First.Value;
sendList.RemoveFirst();
this.kcp.Send(bb);
}
}
if (this.needUpdate)
{
continue;
@@ -84,68 +82,10 @@ namespace cocosocket4unity
{
break;
}
Thread.Yield();
end = DateTime.Now;
Thread.Sleep(0);
end = DateTime.Now;
}
}
}
/// <summary>
/// 处理udp的消息
/// </summary>
/// <param name="bb"></param>
protected override void HandleReceive(ByteBuf bb)
{
string s = System.Text.Encoding.UTF8.GetString(bb.GetRaw(),0,bb.ReadableBytes());
Console.WriteLine("收到消息: "+s);
//this.Send(bb);//回送
}
/// <summary>
/// 异常
/// </summary>
/// <param name="ex"></param>
protected override void HandleException(Exception ex)
{
Console.WriteLine("异常: " + ex);
this.Stop();
}
/// <summary>
/// 超时
/// </summary>
protected override void HandleTimeout()
{
Console.WriteLine("超时: ");
this.Stop();
}
public void Send(ByteBuf content)
{
lock (this.sendList)
{
this.sendList.AddLast(content);
this.needUpdate = true;
}
}
/// <summary>
/// 測試
/// </summary>
/// <param name="args"></param>
public static void Main(string[] args)
{
KcpClient client = new KcpClient(2223);
client.NoDelay(1, 10, 2, 1);//fast
client.WndSize(64, 64);
client.Timeout(10*1000);
client.Connect("10.18.121.15",2222);
client.Start();
Thread.Sleep(2000);
String s = "hi,heoll world! 你好啊!!";
for (int i = 0; i < 2; i++)
{
s = s + s;
}
ByteBuf bb = new ByteBuf(System.Text.Encoding.UTF8.GetBytes(s));
Console.WriteLine(bb.ReadableBytes());
client.Send(bb);
Console.Read();
}
}
}

View File

@@ -13,7 +13,9 @@ namespace cocosocket4unity
protected Kcp kcp;
protected IPEndPoint serverAddr;
protected Object LOCK = new Object();//加锁访问收到的数据
protected LinkedList<byte[]> received;
protected Object SEND_LOCK = new Object();//加锁访问发送列表
protected LinkedList<ByteBuf> received;
protected LinkedList<ByteBuf> sendList;
protected int nodelay;
protected int interval = Kcp.IKCP_INTERVAL;
protected int resend;
@@ -28,7 +30,8 @@ namespace cocosocket4unity
{
client = new UdpClient(port);
kcp = new Kcp(121106, this, null);
this.received = new LinkedList<byte[]>();
this.received = new LinkedList<ByteBuf>();
this.sendList = new LinkedList<ByteBuf>();
}
/// <summary>
/// 连接到地址
@@ -69,7 +72,7 @@ namespace cocosocket4unity
byte[] data=client.EndReceive(ar, ref this.serverAddr);
lock(LOCK)
{
this.received.AddLast(data);
this.received.AddLast(new ByteBuf(data));
this.needUpdate = true;
}
client.BeginReceive(Received, ar.AsyncState);
@@ -78,12 +81,21 @@ namespace cocosocket4unity
this.HandleException(ex);
}
}
/**
* update one kcp
*
* @param addr
* @param kcp
*/
/// <summary>
/// 发送
/// </summary>
/// <param name="content"></param>
public void Send(ByteBuf content)
{
lock (this.SEND_LOCK)
{
this.sendList.AddLast(content);
this.needUpdate = true;
}
}
/// <summary>
/// 更新
/// </summary>
public void Update()
{
//input
@@ -91,14 +103,9 @@ namespace cocosocket4unity
{
while (this.received.Count>0)
{
byte[] dp = this.received.First.Value;
int r=kcp.Input(new ByteBuf(dp));
ByteBuf bb = this.received.First.Value;
kcp.Input(bb);
this.received.RemoveFirst();
if (r < 0)//error
{
this.HandleException(new Exception("kcp输入状态异常"+r));
return;
}
}
}
//receive
@@ -112,6 +119,16 @@ namespace cocosocket4unity
this.lastTime = DateTime.Now;
this.HandleReceive(bb);
}
}
//send
lock (this.SEND_LOCK)
{
while (this.sendList.Count > 0)
{
ByteBuf item = this.sendList.First.Value;
this.kcp.Send(item);
this.sendList.RemoveFirst();
}
}
//update kcp status
int cur = (int)DateTime.Now.Ticks;
@@ -125,7 +142,8 @@ namespace cocosocket4unity
if (this.timeout > 0 && lastTime!=DateTime.MinValue)
{
double del=(DateTime.Now - this.lastTime).TotalMilliseconds;
if (del > this.timeout) {
if (del > this.timeout)
{
this.HandleTimeout();
}
}
@@ -183,5 +201,20 @@ namespace cocosocket4unity
{
this.mtu = mtu;
}
public bool IsStream()
{
return this.kcp.IsStream();
}
public void SetStream(bool stream)
{
this.kcp.SetStream(stream);
}
public void SetMinRto(int min)
{
this.kcp.SetMinRto(min);
}
}
}

View File

@@ -0,0 +1,74 @@
using System;
using LitJson;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Net.Sockets;
using System.Net;
using protocol;
//引用的
using System.Reflection;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Net.Sockets;
using System.Net;
using System.Threading;
namespace cocosocket4unity
{
public class TestKcp : KcpClient
{
public TestKcp(int port): base(port)
{
}
protected override void HandleReceive(ByteBuf bb)
{
string content= System.Text.Encoding.UTF8.GetString(bb.GetRaw());
Console.WriteLine("msg:"+content);
this.Send(bb.Copy());
}
/// <summary>
/// 异常
/// </summary>
/// <param name="ex"></param>
protected override void HandleException(Exception ex)
{
base.HandleException(ex);
}
/// <summary>
/// 超时
/// </summary>
protected override void HandleTimeout()
{
base.HandleTimeout();
}
public static void Main(string[] args)
{
KcpClient client = new TestKcp(2223);
client.NoDelay(1, 10, 2, 1);//fast
client.WndSize(64, 64);
client.Timeout(10*1000);
client.SetMtu(512);
client.SetMinRto(10);
client.Connect("119.29.153.92", 2222);
//client.Connect("127.0.0.1", 2222);
client.Start();
Thread.Sleep(2000);
String s = "hi,heoll world! 你好啊!!";
//for (int i = 0; i < 2; i++)
//{
// s = s + s;
//}
ByteBuf bb = new ByteBuf(System.Text.Encoding.UTF8.GetBytes(s));
Console.WriteLine(bb.ReadableBytes());
client.Send(bb);
Console.Read();
}
}
}

View File

@@ -53,6 +53,7 @@
<Compile Include="ProtoAttribute.cs" />
<Compile Include="Protocal.cs" />
<Compile Include="LVProtocal.cs" />
<Compile Include="TestKcp.cs" />
<Compile Include="USocket.cs" />
<Compile Include="SocketListner.cs" />
<Compile Include="TestListner.cs" />

View File

@@ -1,9 +0,0 @@
D:\projects\cocosocket4unity\cocosocket4unity\bin\Debug\cocosocket4unity.exe
D:\projects\cocosocket4unity\cocosocket4unity\bin\Debug\cocosocket4unity.pdb
D:\projects\cocosocket4unity\cocosocket4unity\obj\x86\Debug\cocosocket4unity.exe
D:\projects\cocosocket4unity\cocosocket4unity\obj\x86\Debug\cocosocket4unity.pdb
D:\projects\open\cocosocket\cocosocket4unity\cocosocket4unity\bin\Debug\cocosocket4unity.exe
D:\projects\open\cocosocket\cocosocket4unity\cocosocket4unity\bin\Debug\cocosocket4unity.pdb
D:\projects\open\cocosocket\cocosocket4unity\cocosocket4unity\bin\Debug\protobuf-net.dll
D:\projects\open\cocosocket\cocosocket4unity\cocosocket4unity\obj\x86\Debug\cocosocket4unity.exe
D:\projects\open\cocosocket\cocosocket4unity\cocosocket4unity\obj\x86\Debug\cocosocket4unity.pdb

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,152 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using UnityEngine;
using System.IO;
namespace cocosocket4unity
{
/// <summary>
/// kcp客戶端程序
/// </summary>
public abstract class KcpClient : KcpOnUdp
{
private LinkedList<ByteBuf> sendList;
protected volatile bool running;
/// <summary>
/// 初始化kcp
/// </summary>
/// <param name="port">监听端口</param>
public KcpClient(int port):base(port)
{
this.sendList = new LinkedList<ByteBuf>();
}
/// <summary>
/// 是否在运行状态
/// </summary>
/// <returns></returns>
public bool IsRunning()
{
return this.running;
}
/// <summary>
/// 停止udp
/// </summary>
public void Stop()
{
if(running)
{
running = false;
try
{
this.client.Close();
}catch (Exception ex)
{
}
}
}
/// <summary>
/// 开启线程开始工作
/// </summary>
public void Start()
{
if (!this.running)
{
this.running = true;
Thread t = new Thread(new ThreadStart(run));//启动发送线程,同步发送
t.IsBackground = true;
t.Start();
}
}
private void run()
{
while (running)
{
DateTime st = DateTime.Now;
this.Update();
lock (this.sendList)
{
while(this.sendList.Count>0)
{
ByteBuf bb=this.sendList.First.Value;
sendList.RemoveFirst();
this.kcp.Send(bb);
}
}
if (this.needUpdate)
{
continue;
}
DateTime end = DateTime.Now;
while ((end - st).TotalMilliseconds < 10)
{
if (this.needUpdate)
{
break;
}
Thread.Sleep(0);
end = DateTime.Now;
}
}
}
/// <summary>
/// 处理udp的消息
/// </summary>
/// <param name="bb"></param>
// protected override void HandleReceive(ByteBuf bb)
// {
// short cmd = bb.ReadShort();
// Type protocolType = MessageQueueHandler.GetProtocolType(cmd);
// if (protocolType == null) {
// Debug.LogWarning(cmd + " - 本地找不到该ProtocolType");
// return;
// }
// byte[] bs = bb.GetRaw();
// MemoryStream stream = new MemoryStream(bs, bb.ReaderIndex(), bb.ReadableBytes());
// object obj = ProtoBuf.Serializer.NonGeneric.Deserialize(protocolType, stream);
// FieldInfo success = obj.GetType().GetField("success");
// if (success != null) {
// if ((bool)success.GetValue(obj) == true) {
// MessageQueueHandler.PushQueue(cmd, obj);
// } else {
// FieldInfo info = obj.GetType().GetField("info");
// if (info != null && info.GetValue(obj) != null) {
// Debug.LogWarning("下行\t出错, cmd=" + cmd + ", type=" + MessageQueueHandler.GetProtocolType(cmd).ToString() + ", " + JsonManager.GetInstance().SerializeObjectDealVector(obj).Replace("\n", ""));
// MessageQueueHandler.PushError(info.GetValue(obj).ToString());
// }
// }
// }
// }
/// <summary>
/// 异常
/// </summary>
/// <param name="ex"></param>
// protected override void HandleException(Exception ex)
// {
// Debug.LogWarning("异常: " + ex);
// this.Stop();
// }
/// <summary>
/// 超时
/// </summary>
// protected override void HandleTimeout()
// {
// Debug.LogWarning("超时: ");
// this.Stop();
// }
public void Send(ByteBuf content)
{
lock (this.sendList)
{
this.sendList.AddLast(content);
this.needUpdate = true;
}
}
/// <summary>
/// 測試
/// </summary>
/// <param name="args"></param>
}
}

View File

@@ -0,0 +1,187 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Net.Sockets;
using System.Net;
namespace cocosocket4unity
{
public abstract class KcpOnUdp : Output
{
protected UdpClient client;
protected Kcp kcp;
protected IPEndPoint serverAddr;
protected Object LOCK = new Object();//加锁访问收到的数据
protected LinkedList<byte[]> received;
protected int nodelay;
protected int interval = Kcp.IKCP_INTERVAL;
protected int resend;
protected int nc;
protected int sndwnd = Kcp.IKCP_WND_SND;
protected int rcvwnd = Kcp.IKCP_WND_RCV;
protected int mtu = Kcp.IKCP_MTU_DEF;
protected volatile bool needUpdate;
protected long timeout;//超时
protected DateTime lastTime;//上次检测时间
public KcpOnUdp(int port)
{
client = new UdpClient(port);
kcp = new Kcp(121106, this, null);
this.received = new LinkedList<byte[]>();
}
/// <summary>
/// 连接到地址
/// </summary>
public void Connect(string host,int port)
{
serverAddr=new IPEndPoint(IPAddress.Parse(host),port);
//mode setting
kcp.NoDelay(nodelay, interval, resend, nc);
kcp.WndSize(sndwnd, rcvwnd);
kcp.SetMtu(mtu);
try
{
this.client.Connect(serverAddr);
client.BeginReceive(Received, client);
}
catch (Exception ex)
{
this.HandleException(ex);
}
}
/// <summary>
/// 超时设定
/// </summary>
public void Timeout(long timeout)
{
this.timeout = timeout;
}
public override void output(ByteBuf msg, Kcp kcp, Object user)
{
this.client.Send(msg.GetRaw(),msg.ReadableBytes());
}
private void Received(IAsyncResult ar)
{
UdpClient client = (UdpClient)ar.AsyncState;
try
{
byte[] data=client.EndReceive(ar, ref this.serverAddr);
lock(LOCK)
{
this.received.AddLast(data);
this.needUpdate = true;
}
client.BeginReceive(Received, ar.AsyncState);
}catch(Exception ex)
{
this.HandleException(ex);
}
}
/**
* update one kcp
*
* @param addr
* @param kcp
*/
public void Update()
{
//input
lock (LOCK)
{
while (this.received.Count>0)
{
byte[] dp = this.received.First.Value;
int r=kcp.Input(new ByteBuf(dp));
this.received.RemoveFirst();
if (r < 0)//error
{
this.HandleException(new Exception("kcp输入状态异常"+r));
return;
}
}
}
//receive
int len;
while ((len = kcp.PeekSize()) > 0)
{
ByteBuf bb = new ByteBuf(len);
int n = kcp.Receive(bb);
if (n > 0)
{
this.lastTime = DateTime.Now;
this.HandleReceive(bb);
}
}
//update kcp status
int cur = (int)DateTime.Now.Ticks;
if (this.needUpdate|| cur >= kcp.GetNextUpdate())
{
kcp.Update(cur);
kcp.SetNextUpdate(kcp.Check(cur));
this.needUpdate = false;
}
//check timeout
if (this.timeout > 0 && lastTime!=DateTime.MinValue)
{
double del=(DateTime.Now - this.lastTime).TotalMilliseconds;
if (del > this.timeout) {
this.HandleTimeout();
}
}
}
/**
* 处理收到的消息
*/
protected abstract void HandleReceive(ByteBuf bb);
/// <summary>
/// 处理异常
/// </summary>
/// <param name="ex"></param>
protected abstract void HandleException(Exception ex);
/// <summary>
/// 超时处理
/// </summary>
protected abstract void HandleTimeout();
/**
* fastest: ikcp_nodelay(kcp, 1, 20, 2, 1) nodelay: 0:disable(default),
* 1:enable interval: internal update timer interval in millisec, default is
* 100ms resend: 0:disable fast resend(default), 1:enable fast resend nc:
* 0:normal congestion control(default), 1:disable congestion control
*
* @param nodelay
* @param interval
* @param resend
* @param nc
*/
public void NoDelay(int nodelay, int interval, int resend, int nc)
{
this.nodelay = nodelay;
this.interval = interval;
this.resend = resend;
this.nc = nc;
}
/**
* set maximum window size: sndwnd=32, rcvwnd=32 by default
*
* @param sndwnd
* @param rcvwnd
*/
public void WndSize(int sndwnd, int rcvwnd)
{
this.sndwnd = sndwnd;
this.rcvwnd = rcvwnd;
}
/**
* change MTU size, default is 1400
*
* @param mtu
*/
public void SetMtu(int mtu)
{
this.mtu = mtu;
}
}
}

View File

@@ -0,0 +1,71 @@
using System;
using LitJson;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Net.Sockets;
using System.Net;
using protocol;
//引用的
using System.Reflection;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Net.Sockets;
using System.Net;
using System.Threading;
namespace cocosocket4unity
{
public class TestKcp : KcpClient
{
public TestKcp(int port): base(port)
{
}
protected override void HandleReceive(ByteBuf bb)
{
string content= System.Text.Encoding.UTF8.GetString(bb.GetRaw());
Console.WriteLine("msg:"+content);
}
/// <summary>
/// 异常
/// </summary>
/// <param name="ex"></param>
protected override void HandleException(Exception ex)
{
this.Stop();
}
/// <summary>
/// 超时
/// </summary>
protected override void HandleTimeout()
{
this.Stop();
}
public static void Main(string[] args)
{
KcpClient client = new TestKcp(2223);
client.NoDelay(1, 10, 2, 1);//fast
client.WndSize(64, 64);
client.Timeout(10*1000);
client.SetMtu(1000);
client.Connect("119.29.153.92", 2222);
client.Start();
Thread.Sleep(2000);
String s = "hi,heoll world! 你好啊!!";
//for (int i = 0; i < 2; i++)
//{
// s = s + s;
//}
ByteBuf bb = new ByteBuf(System.Text.Encoding.UTF8.GetBytes(s));
Console.WriteLine(bb.ReadableBytes());
client.Send(bb);
Console.Read();
}
}
}