/// <summary> /// 패킷을 전송한다. /// 큐가 비어 있을 경우에는 큐에 추가한 뒤 바로 SendAsync매소드를 호출하고, /// 데이터가 들어있을 경우에는 새로 추가만 한다. /// /// 큐잉된 패킷의 전송 시점 : /// 현재 진행중인 SendAsync가 완료되었을 때 큐를 검사하여 나머지 패킷을 전송한다. /// </summary> /// <param name="msg"></param> public void send(CPacket msg) { // 헤더에 패킷 사이즈를 기록한다. msg.record_size(); CPacket[] clones = CPacket.split(msg); foreach (var clone in clones) { lock (this.cs_sending_queue) { // 큐가 비어 있다면 큐에 추가하고 바로 비동기 전송 매소드를 호출한다. if (this.sending_queue.Count <= 0) { this.sending_queue.Enqueue(clone); start_send(); continue; } // 큐에 무언가가 들어 있다면 아직 이전 전송이 완료되지 않은 상태이므로 큐에 추가만 하고 리턴한다. // 현재 수행중인 SendAsync가 완료된 이후에 큐를 검사하여 데이터가 있으면 SendAsync를 호출하여 전송해줄 것이다. Console.WriteLine("Queue is not empty. Copy and Enqueue a msg. protocol id : " + msg.protocol_id); this.sending_queue.Enqueue(clone); } } }
/// <summary> /// 비동기 전송을 시작한다. /// </summary> void start_send() { lock (this.cs_sending_queue) { // 전송이 아직 완료된 상태가 아니므로 데이터만 가져오고 큐에서 제거하진 않는다. CPacket msg = this.sending_queue.Peek(); // 헤더에 패킷 사이즈를 기록한다. msg.record_size(); // 이번에 보낼 패킷 사이즈 만큼 버퍼 크기를 설정하고 this.send_event_args.SetBuffer(this.send_event_args.Offset, msg.position); // 패킷 내용을 SocketAsyncEventArgs버퍼에 복사한다. Array.Copy(msg.buffer, 0, this.send_event_args.Buffer, this.send_event_args.Offset, msg.position); // 비동기 전송 시작. bool pending = this.socket.SendAsync(this.send_event_args); if (!pending) { process_send(this.send_event_args); } } }
public void send(CPacket msg) { msg.record_size(); send(new ArraySegment <byte>(msg.buffer, 0, msg.position)); }