Reading /(Writing) Data from / (to) a Descriptor (Dispatch Sources)

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/chuanyituoku/article/details/38927529
// Read
dispatch_source_t ProcessContentsOfFile(const char* filename)
  {
     // Prepare the file for reading.
     int fd = open(filename, O_RDONLY);
     if (fd == -1)
        return NULL;
     fcntl(fd, F_SETFL, O_NONBLOCK);  // Avoid blocking the read operation
     dispatch_queue_t queue =
  dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
dispatch_source_t readSource = dispatch_source_create(DISPATCH_SOURCE_TYPE_READ, fd, 0, queue);
     if (!readSource)
     {
close(fd);
        return NULL;
     }
     // Install the event handler
     dispatch_source_set_event_handler(readSource, ^{
        size_t estimated = dispatch_source_get_data(readSource) + 1;
        // Read the data into a text buffer.
        char* buffer = (char*)malloc(estimated);
        if (buffer)
        {
           ssize_t actual = read(fd, buffer, (estimated));
           Boolean done = MyProcessFileData(buffer, actual);  // Process the data.
// Release the buffer when done.
           free(buffer);
           // If there is no more data, cancel the source.
           if (done)
              dispatch_source_cancel(readSource);
        }
});
     // Install the cancellation handler
     dispatch_source_set_cancel_handler(readSource, ^{close(fd);});
     // Start reading the file.
     dispatch_resume(readSource);
     return readSource;
}
</pre><pre name="code" class="objc">
// Write
</pre><pre name="code" class="objc"><pre name="code" class="objc">dispatch_source_t WriteDataToFile(const char* filename)
  {
      int fd = open(filename, O_WRONLY | O_CREAT | O_TRUNC,
                        (S_IRUSR | S_IWUSR | S_ISUID | S_ISGID));
      if (fd == -1)
          return NULL;
      fcntl(fd, F_SETFL); // Block during the write.
      dispatch_queue_t queue =
  dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
      dispatch_source_t writeSource =
  dispatch_source_create(DISPATCH_SOURCE_TYPE_WRITE,
if (!writeSource)
{
close(fd);
    return NULL;
}
fd, 0, queue);
dispatch_source_set_event_handler(writeSource, ^{
    size_t bufferSize = MyGetDataSize();
    void* buffer = malloc(bufferSize);
    size_t actual = MyGetData(buffer, bufferSize);
    write(fd, buffer, actual);
free(buffer);
          // Cancel and release the dispatch source when done.
          dispatch_source_cancel(writeSource);
      });
      dispatch_source_set_cancel_handler(writeSource, ^{close(fd);});
      dispatch_resume(writeSource);
      return (writeSource);
}



                                    
展开阅读全文

Error reading from socket

08-26

我写了一个MIDAS程序。rn在一个线程的execute中循环调用:rn只调用了ClientDataSet1.Open;rnClientDataSet1.execute;rn在客户端响应了AfterExecute,rn在服务器端响应了BeforeExecute,AfterExecutern这三个事件响应函数只用到了OwnerData参数.rn为什么运行一阵子之后便出现这样的错误,错误出在(26)(27)两行?如何解决?我都不知道什么时候会调用这个函数TSocketTransport.Receivernrnrnrn(1) function TSocketTransport.Receive(WaitForInput: Boolean; Context: Integer): IDataBlock;rn(2) varrn(3) RetLen, Sig, StreamLen: Integer;rn(4) P: Pointer;rn(5) FDSet: TFDSet;rn(6) TimeVal: PTimeVal;rn(7) RetVal: Integer;rn(8) beginrn(9) Result := nil;rn(10) TimeVal := nil;rn(11) FD_ZERO(FDSet);rn(12) FD_SET(FSocket.SocketHandle, FDSet);rn(13) if not WaitForInput thenrn(14) beginrn(15) New(TimeVal);rn(16) TimeVal.tv_sec := 0;rn(17) TimeVal.tv_usec := 1;rn(18) end;rn(19) RetVal := select(0, @FDSet, nil, nil, TimeVal);rn(20) if Assigned(TimeVal) thenrn(21) FreeMem(TimeVal);rn(22) if RetVal = SOCKET_ERROR thenrn(23) raise ESocketConnectionError.Create(SysErrorMessage(WSAGetLastError));rn(24) if (RetVal = 0) then Exit;rn(25) RetLen := FSocket.ReceiveBuf(Sig, SizeOf(Sig));rn(26) if RetLen <> SizeOf(Sig) thenrn(27) raise ESocketConnectionError.CreateRes(@SSocketReadError);rn(28) if (Sig and CallSig <> CallSig) andrn(29) (Sig and ResultSig <> ResultSig) thenrn(30) raise Exception.CreateRes(@SInvalidDataPacket);rn(31) RetLen := FSocket.ReceiveBuf(StreamLen, SizeOf(StreamLen));rn(32) if RetLen = 0 thenrn(33) raise ESocketConnectionError.CreateRes(@SSocketReadError);rn(34) if RetLen <> SizeOf(StreamLen) thenrn(35) raise ESocketConnectionError.CreateRes(@SSocketReadError);rn(36) Result := TDataBlock.Create as IDataBlock;rn(37) Result.Size := StreamLen;rn(38) Result.Signature := Sig;rn(39) P := Result.Memory;rn(40) Inc(Integer(P), Result.BytesReserved);rn(41) while StreamLen > 0 dorn(42) beginrn(43) RetLen := FSocket.ReceiveBuf(P^, StreamLen);rn(44) if RetLen = 0 thenrn(45) raise ESocketConnectionError.CreateRes(@SSocketReadError);rn(46) if RetLen > 0 thenrn(47) beginrn(48) Dec(StreamLen, RetLen);rn(49) Inc(Integer(P), RetLen);rn(50) end;rn(51) end;rn(52) if StreamLen <> 0 thenrn(53) raise ESocketConnectionError.CreateRes(@SInvalidDataPacket);rn(54) InterceptIncoming(Result);rn(55) end;rnrn 论坛

没有更多推荐了,返回首页