2016-10-22 11 views
5
Linux (Ubuntu 16.04) .NET Çekirdeği bir unix soket oluşturduk

yılında .NET Çekirdek bir Unix alan soketi bağlanmak için?nasıl C#

NET Çekirdek API ama tüm IP adresleri ile ilk anlaşma dışında çeşitli Socket.Connect seçeneklerini listeler:

public void Connect(EndPoint remoteEP) 
public void Connect(IPAddress address, int port) 
public void Connect(IPAddress[] addresses, int port) 
public void Connect(string host, int port) 

System.Net API bir DNSEndpoint ve IPEndpoint tanımlar ama bulmam gibi olamaz bir UnixEndpoint veya benzer sınıf olmak görünmüyor Socket.Connect(EndPoint remoteEP)

+0

kullanıyorum @PeterDuniho. Linux üzerinde NET çekirdeği (bunu yansıtmak için sorumu güncelledi). Kesinlikle bir unix alan soketi açmak için POSIX çağrısı yapmak için bir yol var mı? Lütfen bunu kopya olarak işaretleyin, işaretli kopya bu soruyla ilgili değil. – Caleb

cevap

4

geçmek yerleşik bir UnixEndPoint .NET Core sınıf veya bu yazı teker teker uygulayan bir kütüphane. UnixEndPoint class from the Mono.Posix proje kolayca Ancak .NET Çekirdek ile çalışmak için adapte edilebilir:

projenizde Bu sınıf ile
// copied from https://github.com/mono/mono/blob/master/mcs/class/Mono.Posix/Mono.Unix/UnixEndPoint.cs 

// 
// Mono.Unix.UnixEndPoint: EndPoint derived class for AF_UNIX family sockets. 
// 
// Authors: 
// Gonzalo Paniagua Javier ([email protected]) 
// 
// (C) 2003 Ximian, Inc (http://www.ximian.com) 
// 

// 
// Permission is hereby granted, free of charge, to any person obtaining 
// a copy of this software and associated documentation files (the 
// "Software"), to deal in the Software without restriction, including 
// without limitation the rights to use, copy, modify, merge, publish, 
// distribute, sublicense, and/or sell copies of the Software, and to 
// permit persons to whom the Software is furnished to do so, subject to 
// the following conditions: 
// 
// The above copyright notice and this permission notice shall be 
// included in all copies or substantial portions of the Software. 
// 
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE 
// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 
// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 
// 

using System.Net.Sockets; 
using System.Text; 

namespace System.Net 
{ 

    public class UnixEndPoint : EndPoint 
    { 
     string filename; 

     public UnixEndPoint (string filename) 
     { 
      if (filename == null) 
       throw new ArgumentNullException ("filename"); 

      if (filename == "") 
       throw new ArgumentException ("Cannot be empty.", "filename"); 
      this.filename = filename; 
     } 

     public string Filename { 
      get { 
       return(filename); 
      } 
      set { 
       filename=value; 
      } 
     } 

     public override AddressFamily AddressFamily { 
      get { return AddressFamily.Unix; } 
     } 

     public override EndPoint Create (SocketAddress socketAddress) 
     { 
      /* 
      * Should also check this 
      * 
      int addr = (int) AddressFamily.Unix; 
      if (socketAddress [0] != (addr & 0xFF)) 
       throw new ArgumentException ("socketAddress is not a unix socket address."); 
      if (socketAddress [1] != ((addr & 0xFF00) >> 8)) 
       throw new ArgumentException ("socketAddress is not a unix socket address."); 
      */ 

      if (socketAddress.Size == 2) { 
       // Empty filename. 
       // Probably from RemoteEndPoint which on linux does not return the file name. 
       UnixEndPoint uep = new UnixEndPoint ("a"); 
       uep.filename = ""; 
       return uep; 
      } 
      int size = socketAddress.Size - 2; 
      byte [] bytes = new byte [size]; 
      for (int i = 0; i < bytes.Length; i++) { 
       bytes [i] = socketAddress [i + 2]; 
       // There may be junk after the null terminator, so ignore it all. 
       if (bytes [i] == 0) { 
        size = i; 
        break; 
       } 
      } 

      string name = Encoding.UTF8.GetString (bytes, 0, size); 
      return new UnixEndPoint (name); 
     } 

     public override SocketAddress Serialize() 
     { 
      byte [] bytes = Encoding.UTF8.GetBytes (filename); 
      SocketAddress sa = new SocketAddress (AddressFamily, 2 + bytes.Length + 1); 
      // sa [0] -> family low byte, sa [1] -> family high byte 
      for (int i = 0; i < bytes.Length; i++) 
       sa [2 + i] = bytes [i]; 

      //NULL suffix for non-abstract path 
      sa[2 + bytes.Length] = 0; 

      return sa; 
     } 

     public override string ToString() { 
      return(filename); 
     } 

     public override int GetHashCode() 
     { 
      return filename.GetHashCode(); 
     } 

     public override bool Equals (object o) 
     { 
      UnixEndPoint other = o as UnixEndPoint; 
      if (other == null) 
       return false; 

      return (other.filename == filename); 
     } 
    } 
} 

, priz şöyle bağlanabilir: Ben

var unixSocket = "/var/run/mysqld/mysqld.sock"; 
var socket = new Socket(AddressFamily.Unix, SocketType.Stream, ProtocolType.IP); 
var unixEp = new UnixEndPoint(unixSocket); 
socket.Connect(unixEp);