这是问题所在。我想通过 tcp socket 连接将 win32 api app 连接到c#dot net app。 C#服务器看起来像这样:
public class MyServer
{
// Incoming data from the client.
public static string data = null;
public static void StartListening()
{
// Data buffer for incoming data.
byte[] bytes = new Byte[1024];
// Establish the local endpoint for the socket.
// Dns.GetHostName returns the name of the
// host running the application.
IPHostEntry ipHostInfo = Dns.Resolve(Dns.GetHostName());
IPAddress ipAddress = ipHostInfo.AddressList[0];
IPEndPoint localEndPoint = new IPEndPoint(ipAddress, 11000);
// Create a TCP/IP socket.
Socket listener = new Socket(AddressFamily.InterNetwork,
SocketType.Stream, ProtocolType.Tcp);
// Bind the socket to the local endpoint and
// listen for incoming connections.
try
{
listener.Bind(localEndPoint);
listener.Listen(10);
// Start listening for connections.
while (true)
{
Console.WriteLine("Waiting for a connection...");
// Program is suspended while waiting for an incoming connection.
Socket handler = listener.Accept();
data = null;
// An incoming connection needs to be processed.
while (true)
{
bytes = new byte[1024];
int bytesRec = handler.Receive(bytes);
data += Encoding.ASCII.GetString(bytes, 0, bytesRec);
if (data.IndexOf("\n") > -1)
{
Console.WriteLine("Text received : {0}", data);
data=null;
}
}
}
}
catch (Exception e)
{
Console.WriteLine(e.ToString());
}
Console.WriteLine("\nPress ENTER to continue...");
Console.Read();
}
public static int Main(String[] args)
{
StartListening();
return 0;
}
}
这很简单,不完美,但事实证明它可以完成它的工作。 Win32 API 程序如下:
DWORD WINAPI myThread(LPVOID lpParameter) {
int iResult;
char recvbuf[DEFAULT_BUFLEN];
//addrinfo holds host address information
SOCKADDR_IN clientService;
SOCKET ConnectSocket = INVALID_SOCKET;
int recvbuflen = DEFAULT_BUFLEN;
char *sendbuf = "this is a test";
// Initialize Winsock
iResult = WSAStartup(MAKEWORD(2,2), &wsaData);
if (iResult != 0) {
printf("WSAStartup failed: %d\n", iResult);
return 1;
}
ConnectSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
if (ConnectSocket == INVALID_SOCKET) {
printf("Error at socket(): %ld\n", WSAGetLastError());
WSACleanup();
return 1;
}
clientService.sin_family = AF_INET;
clientService.sin_addr.s_addr = inet_addr("127.0.0.1");
clientService.sin_port = htons(11000);
iResult = connect(ConnectSocket, (SOCKADDR *) & clientService, sizeof (clientService));
if (iResult == SOCKET_ERROR) {
closesocket(ConnectSocket);
ConnectSocket = INVALID_SOCKET;
}
// Should really try the next address returned by getaddrinfo
// if the connect call failed
// But for this simple example we just free the resources
// returned by getaddrinfo and print an error message
if (ConnectSocket == INVALID_SOCKET) {
printf("Unable to connect to server!\n");
WSACleanup();
return 1;
}
iResult = send(ConnectSocket, sendbuf, (int) strlen(sendbuf), 0);
if (iResult == SOCKET_ERROR) {
printf("send failed: %d\n", WSAGetLastError());
closesocket(ConnectSocket);
WSACleanup();
return 1;
}
printf("Bytes Sent: %ld\n", iResult);
// shutdown the connection for sending since no more data will be sent
// the client can still use the ConnectSocket for receiving data
iResult = shutdown(ConnectSocket, SD_SEND);
if (iResult == SOCKET_ERROR) {
printf("shutdown failed: %d\n", WSAGetLastError());
closesocket(ConnectSocket);
WSACleanup();
return 1;
}
}
简化的主要是:
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
LPSTR lpCmdLine, int nCmdShow)
{
DWORD myThreadID;
//thread creation
myHandle = CreateThread(0, 0, myThread, &myCounter, 0, &myThreadID);
while(1 > 0)
{
//do some stuffs
}
return 0;
}
所以基本上我正在尝试连接端口 11000 上的本地主机。首先启动服务器,然后当我调试 win32 api 程序时,在调用connect
函数后得到 SOCKET_ERROR 。
inet_addr是否可能返回错误的IP地址版本(6而不是4)?
感谢。
P.S。问题绝对不在网络中,因为这是与localhost的环回连接,并且正如所提到的那样,服务器被测试为在同一台机器,地址和端口上使用另一个客户端(用c#编写)。
我在调试期间注意到的另一个有趣的事实是clientService.sin_addr.s_addr
是16777343
,但ipAddress.Address
的值是2399212554
。
更新:我刚刚使用提供的winsock server测试了winapi客户端,效果非常好。这意味着问题是c#服务器和winapi客户端之间不兼容。那么问题是什么是不兼容的? IP地址,套接字配置还是别的什么?