在 C# 中使用 C 套接字时出现问题
Issue when Using c sockets in c#
我正在尝试使用 c# 中的系统套接字创建套接字。
我编写了以下代码:
using System;
using System.Net;
using System.Runtime.InteropServices;
namespace test_socket
{
public class Program
{
[DllImport("libc", EntryPoint = "socket", SetLastError = true)]
public static extern int socket(int domain, int type, int protocol);
//public static extern int socket(AddressFamily domain, SocketType type, ProtocolFamily protocol);
[DllImport("libc", EntryPoint = "close", SetLastError = true)]
public static extern int close(int handle);
[DllImport("libc", EntryPoint = "connect", SetLastError = true)]
public static extern int connect(int socket, sockaddr_in addr, int socklen_t);
[StructLayout(LayoutKind.Sequential)]
public struct sockaddr_in
{
public byte sin_len;
public byte sin_family;
public ushort sin_port;
public uint sin_addr;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 8)]
public byte[] sin_zero;
};
public static void Main() {
Console.WriteLine("Hello World");
int msock = socket(2, 1, 0); //AF_INET, SOCK_STREAM, 0
IPAddress ipa = IPAddress.Parse("127.0.0.1");
int sock_struct_size = Marshal.SizeOf(typeof(sockaddr_in));
sockaddr_in sin = new sockaddr_in()
{
sin_len = (byte)sock_struct_size,
sin_family = 2, //2
sin_port = (ushort)IPAddress.HostToNetworkOrder((short)4569),
#pragma warning disable 618
sin_addr = (uint)ipa.Address,
#pragma warning restore 618
sin_zero = new byte[8] { 0, 0, 0, 0, 0, 0, 0, 0 }
};
var test_sock = connect(msock, sin, sock_struct_size);
Console.WriteLine(test_sock);
Console.WriteLine(Marshal.GetLastWin32Error());
}
}
}
我在尝试连接我的套接字时总是收到 -1。
我当然可以在本地连接到端口 4569:
远程登录 127.0.0.1 4569
正在尝试 127.0.0.1...
连接到 localhost.
我不知道我错过了什么。
如果测试上述代码,请将端口 4569 替换为打开的端口,例如 22 (ssh)。
使用 dotnetcore 3.1 和 mac os 10.15.3
进行测试
我制作了一个示例 C++ 项目来测试套接字,它工作正常:
// Client side C/C++ program to demonstrate Socket programming
#include <stdio.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <string.h>
#define PORT 4569
int main(int argc, char const *argv[])
{
int sock = 0, valread;
struct sockaddr_in serv_addr;
char *hello = "Hello from client";
char buffer[1024] = {0};
if ((sock = socket(AF_INET, SOCK_STREAM, 0)) < 0)
{
printf("\n Socket creation error \n");
return -1;
}
printf("sizeof: %lu", sizeof(serv_addr));
serv_addr.sin_family = AF_INET;
serv_addr.sin_port = htons(PORT);
printf("port: %hu", serv_addr.sin_port);
// Convert IPv4 and IPv6 addresses from text to binary form
if(inet_pton(AF_INET, "127.0.0.1", &serv_addr.sin_addr)<=0)
{
printf("\nInvalid address/ Address not supported \n");
return -1;
}
uint x = serv_addr.sin_addr.s_addr;
printf("addr: %du", x);
if (connect(sock, (struct sockaddr *)&serv_addr, sizeof(serv_addr)) < 0)
{
printf("\nConnection Failed \n");
return -1;
}
send(sock , hello , strlen(hello) , 0 );
printf("Hello message sent\n");
valread = read( sock , buffer, 1024);
printf("%s\n",buffer );
return 0;
}
我检查了 port/ip 的 struct size 和 int 值,它们也匹配
@bmigette 找到了答案,但是在对这个问题悬赏之后,他没有足够的声誉 post 自己:
"[...] 结果是您需要在套接字函数之后立即调用 GetLastWin32Error [...] 请在此处为感兴趣的人找到答案:pastebin.com/raw/j6w8HLgp"
以防将来 link 不可用,最终解决方案中的工作主要功能如下:
public unsafe static void Main() {
Console.WriteLine(" World");
int msock = socket(AF_INET, SOCK_STREAM, 0);
IPAddress ipa = IPAddress.Parse("127.0.0.1");
int sock_struct_size = Marshal.SizeOf(typeof(sockaddr_in));
in_addr ina = new in_addr();
var adbytes = ipa.GetAddressBytes();
ina.s_addr[0] = adbytes[0];
ina.s_addr[1] = adbytes[1];
ina.s_addr[2] = adbytes[2];
ina.s_addr[3] = adbytes[3];
sockaddr_in sin = new sockaddr_in()
{
sin_family = 2, //2
sin_port = (ushort)IPAddress.HostToNetworkOrder((short)4569),
};
sin.sin_addr = ina; //.s_addr = (ushort)ipa.Address;
Console.WriteLine(Marshal.SizeOf(sin));
var test_sock =connect(msock, (sockaddr*)&sin, sock_struct_size);
var errno = Marshal.GetLastWin32Error();
Console.WriteLine(test_sock);
Console.WriteLine(errno);
}
我正在尝试使用 c# 中的系统套接字创建套接字。
我编写了以下代码:
using System;
using System.Net;
using System.Runtime.InteropServices;
namespace test_socket
{
public class Program
{
[DllImport("libc", EntryPoint = "socket", SetLastError = true)]
public static extern int socket(int domain, int type, int protocol);
//public static extern int socket(AddressFamily domain, SocketType type, ProtocolFamily protocol);
[DllImport("libc", EntryPoint = "close", SetLastError = true)]
public static extern int close(int handle);
[DllImport("libc", EntryPoint = "connect", SetLastError = true)]
public static extern int connect(int socket, sockaddr_in addr, int socklen_t);
[StructLayout(LayoutKind.Sequential)]
public struct sockaddr_in
{
public byte sin_len;
public byte sin_family;
public ushort sin_port;
public uint sin_addr;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 8)]
public byte[] sin_zero;
};
public static void Main() {
Console.WriteLine("Hello World");
int msock = socket(2, 1, 0); //AF_INET, SOCK_STREAM, 0
IPAddress ipa = IPAddress.Parse("127.0.0.1");
int sock_struct_size = Marshal.SizeOf(typeof(sockaddr_in));
sockaddr_in sin = new sockaddr_in()
{
sin_len = (byte)sock_struct_size,
sin_family = 2, //2
sin_port = (ushort)IPAddress.HostToNetworkOrder((short)4569),
#pragma warning disable 618
sin_addr = (uint)ipa.Address,
#pragma warning restore 618
sin_zero = new byte[8] { 0, 0, 0, 0, 0, 0, 0, 0 }
};
var test_sock = connect(msock, sin, sock_struct_size);
Console.WriteLine(test_sock);
Console.WriteLine(Marshal.GetLastWin32Error());
}
}
}
我在尝试连接我的套接字时总是收到 -1。 我当然可以在本地连接到端口 4569:
远程登录 127.0.0.1 4569
正在尝试 127.0.0.1... 连接到 localhost.
我不知道我错过了什么。
如果测试上述代码,请将端口 4569 替换为打开的端口,例如 22 (ssh)。
使用 dotnetcore 3.1 和 mac os 10.15.3
进行测试我制作了一个示例 C++ 项目来测试套接字,它工作正常:
// Client side C/C++ program to demonstrate Socket programming
#include <stdio.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <string.h>
#define PORT 4569
int main(int argc, char const *argv[])
{
int sock = 0, valread;
struct sockaddr_in serv_addr;
char *hello = "Hello from client";
char buffer[1024] = {0};
if ((sock = socket(AF_INET, SOCK_STREAM, 0)) < 0)
{
printf("\n Socket creation error \n");
return -1;
}
printf("sizeof: %lu", sizeof(serv_addr));
serv_addr.sin_family = AF_INET;
serv_addr.sin_port = htons(PORT);
printf("port: %hu", serv_addr.sin_port);
// Convert IPv4 and IPv6 addresses from text to binary form
if(inet_pton(AF_INET, "127.0.0.1", &serv_addr.sin_addr)<=0)
{
printf("\nInvalid address/ Address not supported \n");
return -1;
}
uint x = serv_addr.sin_addr.s_addr;
printf("addr: %du", x);
if (connect(sock, (struct sockaddr *)&serv_addr, sizeof(serv_addr)) < 0)
{
printf("\nConnection Failed \n");
return -1;
}
send(sock , hello , strlen(hello) , 0 );
printf("Hello message sent\n");
valread = read( sock , buffer, 1024);
printf("%s\n",buffer );
return 0;
}
我检查了 port/ip 的 struct size 和 int 值,它们也匹配
@bmigette 找到了答案,但是在对这个问题悬赏之后,他没有足够的声誉 post 自己:
"[...] 结果是您需要在套接字函数之后立即调用 GetLastWin32Error [...] 请在此处为感兴趣的人找到答案:pastebin.com/raw/j6w8HLgp"
以防将来 link 不可用,最终解决方案中的工作主要功能如下:
public unsafe static void Main() {
Console.WriteLine(" World");
int msock = socket(AF_INET, SOCK_STREAM, 0);
IPAddress ipa = IPAddress.Parse("127.0.0.1");
int sock_struct_size = Marshal.SizeOf(typeof(sockaddr_in));
in_addr ina = new in_addr();
var adbytes = ipa.GetAddressBytes();
ina.s_addr[0] = adbytes[0];
ina.s_addr[1] = adbytes[1];
ina.s_addr[2] = adbytes[2];
ina.s_addr[3] = adbytes[3];
sockaddr_in sin = new sockaddr_in()
{
sin_family = 2, //2
sin_port = (ushort)IPAddress.HostToNetworkOrder((short)4569),
};
sin.sin_addr = ina; //.s_addr = (ushort)ipa.Address;
Console.WriteLine(Marshal.SizeOf(sin));
var test_sock =connect(msock, (sockaddr*)&sin, sock_struct_size);
var errno = Marshal.GetLastWin32Error();
Console.WriteLine(test_sock);
Console.WriteLine(errno);
}