我在设置赏金时编辑了我的问题。 我想从WinAPI调用/ DllImport WSAAsyncSelect()并使用它,就像我在Delphi / C ++中使用它一样
例如 - Delphi
//Async CallBack handler Declaration
procedure MessageHandler(var Msg:Tmessage);Message WM_WINSOCK_ASYNC_MSG;
//Where i setup the Async
dwError := WSAAsyncSelect(Sock, form1.handle, WM_WINSOCK_ASYNC_MSG, FD_CLOSE or FD_READ);
//Async Callback Handler
procedure Tform1.MessageHandler(var Msg:Tmessage);
begin
case WSAGetSelectEvent(MSG.LParam) of //LParam is FD_READ/FR_CLOSE/FD_WRITE
FD_READ: OnSocketRead(MSG.WParam); //WPARAM is the Socket itself.
FD_CLOSE: OnSocketClose(MSG.WParam);
end;
end;
提前致谢!
答案 0 :(得分:4)
我做到了! Finaly !!!
WSAAsyncSelect()结构
[DllImport("wsock32.dll")]
public static extern int WSAAsyncSelect(
int socket,
int hWnd,
int wMsg,
int lEvent
);
WS2 Class
public class WS2
{
public static Socket sock;
public static byte[] data = new byte[8096];
public static int server = 0;
public static bool forced = true;
public static void Close()
{
//Extern.closesocket(sock.Handle.ToInt32());
//Extern.WSACleanup();
sock.Shutdown(SocketShutdown.Both);
sock.Close();
if (forced)
{
Connect();
}
}
public static void ConnectTo(string ip,int port)
{
sock = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
sock.Connect(ip, port);
int handle = 0;
var form1 = Form.ActiveForm as FormMain;
if (form1 != null)
handle = form1.GetHandle;
if (handle == 0)
{
FormMain.PerformActionOnMainForm(form => form.memo.Text += "An error occured: Error code WS_01_ASYNC_HANDLE");
return;
}
Extern.WSAAsyncSelect(sock.Handle.ToInt32(), handle, Values.MESSAGE_ASYNC, Values.FD_READ | Values.FD_CLOSE);
}
public static void Connect()
{
//Get IP && port
string ip = GetIPFromHost("gwgt1.joymax.com");
if (ip == "")
{
ip = GetIPFromHost("gwgt2.joymax.com");
if (ip == "")
{
}
server +=2;
}
else
server +=1;
int port = 15779;
//
ConnectTo(ip, port);
}
public static void Receive()
{
int size = sock.Receive(data);
if (size == 0)
{
FormMain.PerformActionOnMainForm(form => form.memo.Text += "An error occured: Error Code WS_02_RECV_BEGN");
}
Main.Handle(data, size);
}
public static string GetIPFromHost(string HostName)
{
IPHostEntry ip;
try
{
ip = Dns.GetHostEntry(HostName);
}
catch (Exception)
{
return "";
}
return ip.AddressList[0].ToString();
}
}
Form类中的WndProc。
protected override void WndProc(ref Message m)
{
if (m.Msg == Values.MESSAGE_ASYNC)
{
switch (m.LParam.ToInt32())
{
case Values.FD_READ:
WS2.Receive();
break;
case Values.FD_WRITE: break;
case Values.FD_CLOSE:
WS2.Close();
break;
default: break;
}
}
else
{
base.WndProc(ref m);
}
}
获取句柄:
public int GetHandle
{
get
{
if (this.InvokeRequired)
{
return (int)this.Invoke((GetHandleDelegate)delegate
{
return this.Handle.ToInt32();
});
}
return this.Handle.ToInt32();
}
}
private delegate int GetHandleDelegate();
答案 1 :(得分:0)
(编辑:主要与原始问题有关,在编辑之前加上赏金)
我最近一直在关注这个问题 - 请参阅Async without the pain。请注意最后关于使用委托版本的注释 - 这会略微简化调用。
作为更新,最终的代码看起来如下所示,因为它发现与F#在引擎盖下使用的内容非常相似:
public static void RunAsync<T>(
Func<AsyncCallback, object, IAsyncResult> begin,
Func<IAsyncResult, T> end,
Action<Func<T>> callback) {
begin(ar => {
T result;
try {
result = end(ar); // ensure end called
callback(() => result);
} catch (Exception ex) {
callback(() => { throw ex; });
}
}, null);
}