[英]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 替換為已打開的端口,例如 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找到了答案,但是在對這個問題懸賞之后,他沒有足夠的聲譽來自己發布它:
“[...] 事實證明您需要在套接字函數之后立即調用 GetLastWin32Error [...] 請在此處為感興趣的人找到答案: pastebin.com/raw/j6w8HLgp ”
如果將來鏈接不可用,最終解決方案中的工作主要功能如下:
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);
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.