{"id":374476,"date":"2024-05-21T06:01:24","date_gmt":"2024-05-21T06:01:24","guid":{"rendered":"http:\/\/savepearlharbor.com\/?p=374476"},"modified":"-0001-11-30T00:00:00","modified_gmt":"-0001-11-29T21:00:00","slug":"","status":"publish","type":"post","link":"https:\/\/savepearlharbor.com\/?p=374476","title":{"rendered":"<span>Enabling Cross-Process Dialogue with C# Sockets<\/span>"},"content":{"rendered":"<div><!--[--><!--]--><\/div>\n<div id=\"post-content-body\">\n<div>\n<div class=\"article-formatted-body article-formatted-body article-formatted-body_version-2\">\n<div xmlns=\"http:\/\/www.w3.org\/1999\/xhtml\">\n<h3>Introduction<\/h3>\n<p>In the ever-evolving landscape of software development, communication between processes has been a fundamental requirement since the inception of computer networking. As technology advanced, the need for efficient and reliable inter-process communication (IPC) mechanisms became increasingly crucial. One such mechanism that has stood the test of time is the socket.<br \/>Sockets trace their origins back to the early days of computer networking in the 1970s. The concept was first introduced in the Unix operating system by researchers at the University of California, Berkeley, as part of their work on the ARPANET project, which eventually evolved into the modern internet. Sockets were designed to provide a standardized interface for network communication, allowing processes to exchange data across different machines and networks.<br \/>Initially, sockets were primarily used for network programming tasks, such as building client-server applications and facilitating communication between distributed systems. However, their versatility soon became apparent, and sockets found their way into various domains, including inter-process communication (IPC) within a single machine.<br \/>Over the years, sockets have undergone numerous enhancements and standardizations, with the Berkeley Software Distribution (BSD) sockets becoming the de facto standard for network programming. This standard was later adopted by other operating systems, including Microsoft Windows, ensuring cross-platform compatibility and enabling widespread adoption.<br \/>In the world of software development, communication between processes is a common requirement, whether it\u2019s a client-server architecture, distributed systems, or inter-process communication (IPC). Sockets provide a powerful mechanism for processes to exchange data efficiently and reliably. This article explores a simple implementation of a TCP client-server communication using sockets in C#, showcasing the versatility and robustness of this time-tested technology.<\/p>\n<h3>The Codebase<\/h3>\n<h3>1.\u00a0Config.cs:<\/h3>\n<p>This class serves as a base for both the server and the client. It defines the IP address and port number to be used for communication and creates a shared Socket object.<\/p>\n<pre><code class=\"cs\">using System.Net.Sockets; using System.Net;  namespace amSocket;  public class Config {     static string _ip = \"127.0.0.1\";     static int _port = 8088;      protected static IPEndPoint _endPoint = new(IPAddress.Parse(_ip), _port);     protected static Socket _socket = new(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); }<\/code><\/pre>\n<h3>2.\u00a0Message.cs:<\/h3>\n<p>This class represents the data structure that is sent between the client and the server. It contains an ID, a source string, and a message string. The Pack method converts the Message object into a string representation, separating the fields with the | character.<\/p>\n<pre><code class=\"cs\">namespace amSocket;  public class Message {     public int id = 0;     public string src = \"\";     public string msg = \"\";        public Message(string packed)     {         var ar = packed.Split('|');         id = int.Parse(ar[0]);         src = ar[1];         msg = ar[2];     }        public string Pack() { return $\"{id}|{src}|{msg}\"; } } <\/code><\/pre>\n<h3>3.\u00a0Client.cs:<\/h3>\n<p>This class handles the client-side logic for sending data to the server. The Send method connects to the specified IP and port, converts the provided Message object to a string, and sends it to the server.<\/p>\n<pre><code class=\"cs\">using System.Text;  namespace amSocket;  public class Client : Config {     public static void Send(Message b)     {         _socket.Connect(_endPoint);          string message = b.Pack();         byte[] messageBytes = Encoding.UTF8.GetBytes(message);         _socket.Send(messageBytes);         _socket.Close();     } }<\/code><\/pre>\n<h3>4.\u00a0Server.cs:<\/h3>\n<p>This class handles the server-side logic for listening for incoming connections. The StartListen method binds the server socket to the specified IP and port, starts listening for connections, and accepts incoming connections asynchronously. When a connection is accepted, it receives data from the client and passes it to the provided callback as a Message object.<\/p>\n<pre><code class=\"cs\">using System.Net.Sockets; using System.Text;  namespace amSocket;  public class Server : Config {     static bool _needToClose = false;     public static void StartListen(Action&lt;Message> OnSocketMessage)     {         Task.Run(async () =>         {             try             {                 _socket.Bind(_endPoint);                 _socket.Listen(5);                  while (true)                 {                     var listener = _socket.Accept();                     var buffer = new byte[1_024];                     var received = await listener.ReceiveAsync(buffer, SocketFlags.None);                     var response = Encoding.UTF8.GetString(buffer, 0, received);                      Message b = new(response);                     OnSocketMessage(b);                      if (_needToClose) break;                 }             }             catch (Exception ex)             {                 Console.WriteLine(ex.ToString());             }         });     }     public static void StopListen()     {         _needToClose = true;         _socket.Close();     } }  <\/code><\/pre>\n<h3>Usage<\/h3>\n<p>To use this code, follow these steps:<\/p>\n<h3>1.\u00a0Start the Server:<\/h3>\n<p>Create an instance of the Server class and call the StartListen method, passing a callback function to handle incoming messages:<\/p>\n<pre><code class=\"cs\">Server.StartListen(OnSocketMessage);  void OnSocketMessage(Message b) {     Console.WriteLine($\"Received message: {b.msg} from {b.src} with ID {b.id}\"); }<\/code><\/pre>\n<h3>2.\u00a0Send Data from the Client:<\/h3>\n<p>Create an instance of the Client class and call the Send method with a Message object containing the data you want to send:<\/p>\n<pre><code class=\"cs\">Message b = new Message { id = 1, src = \"ClientApp\", msg = \"Hello, Server!\" }; Client.Send(b);<\/code><\/pre>\n<p>The server will receive the message and print it to the console:<\/p>\n<pre><code>Received message: Hello, Server! from ClientApp with ID 1<\/code><\/pre>\n<h3>Considerations<\/h3>\n<p>This implementation is a simple example and does not include error handling, concurrency management, or other advanced features that would be necessary for a production-ready application. Here are some considerations:<\/p>\n<ul>\n<li>\n<p><strong>Error Handling:<\/strong>\u00a0The code does not handle exceptions or errors that may occur during communication, such as network issues or invalid data.<\/p>\n<\/li>\n<li>\n<p><strong>Concurrency:<\/strong>\u00a0The server implementation uses a single thread to handle incoming connections. In a real-world scenario, you would need to handle multiple concurrent connections using techniques like asynchronous programming or threading.<\/p>\n<\/li>\n<li>\n<p><strong>Security:<\/strong>\u00a0The implementation does not include any security measures, such as encryption or authentication. In a production environment, you would need to ensure secure communication channels.<\/p>\n<\/li>\n<li>\n<p><strong>Scalability:<\/strong>\u00a0The current implementation is limited to a single server instance. For large-scale applications, you may need to consider load balancing, clustering, or other scalability techniques.<\/p>\n<\/li>\n<\/ul>\n<p>Despite its simplicity, this codebase serves as a good starting point for understanding the fundamentals of socket-based communication in C#. With proper enhancements and modifications, it can be adapted to meet the requirements of more complex and robust applications.<\/p>\n<\/p>\n<\/div>\n<\/div>\n<\/div>\n<p><!----><!----><\/div>\n<p><!----><!----><br \/> \u0441\u0441\u044b\u043b\u043a\u0430 \u043d\u0430 \u043e\u0440\u0438\u0433\u0438\u043d\u0430\u043b \u0441\u0442\u0430\u0442\u044c\u0438 <a href=\"https:\/\/habr.com\/ru\/articles\/809867\/\"> https:\/\/habr.com\/ru\/articles\/809867\/<\/a><\/p>\n","protected":false},"excerpt":{"rendered":"<div><!--[--><!--]--><\/div>\n<div id=\"post-content-body\">\n<div>\n<div class=\"article-formatted-body article-formatted-body article-formatted-body_version-2\">\n<div xmlns=\"http:\/\/www.w3.org\/1999\/xhtml\">\n<h3>Introduction<\/h3>\n<p>In the ever-evolving landscape of software development, communication between processes has been a fundamental requirement since the inception of computer networking. As technology advanced, the need for efficient and reliable inter-process communication (IPC) mechanisms became increasingly crucial. One such mechanism that has stood the test of time is the socket.<br \/>Sockets trace their origins back to the early days of computer networking in the 1970s. The concept was first introduced in the Unix operating system by researchers at the University of California, Berkeley, as part of their work on the ARPANET project, which eventually evolved into the modern internet. Sockets were designed to provide a standardized interface for network communication, allowing processes to exchange data across different machines and networks.<br \/>Initially, sockets were primarily used for network programming tasks, such as building client-server applications and facilitating communication between distributed systems. However, their versatility soon became apparent, and sockets found their way into various domains, including inter-process communication (IPC) within a single machine.<br \/>Over the years, sockets have undergone numerous enhancements and standardizations, with the Berkeley Software Distribution (BSD) sockets becoming the de facto standard for network programming. This standard was later adopted by other operating systems, including Microsoft Windows, ensuring cross-platform compatibility and enabling widespread adoption.<br \/>In the world of software development, communication between processes is a common requirement, whether it\u2019s a client-server architecture, distributed systems, or inter-process communication (IPC). Sockets provide a powerful mechanism for processes to exchange data efficiently and reliably. This article explores a simple implementation of a TCP client-server communication using sockets in C#, showcasing the versatility and robustness of this time-tested technology.<\/p>\n<h3>The Codebase<\/h3>\n<h3>1.\u00a0Config.cs:<\/h3>\n<p>This class serves as a base for both the server and the client. It defines the IP address and port number to be used for communication and creates a shared Socket object.<\/p>\n<pre><code class=\"cs\">using System.Net.Sockets; using System.Net;  namespace amSocket;  public class Config {     static string _ip = \"127.0.0.1\";     static int _port = 8088;      protected static IPEndPoint _endPoint = new(IPAddress.Parse(_ip), _port);     protected static Socket _socket = new(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); }<\/code><\/pre>\n<h3>2.\u00a0Message.cs:<\/h3>\n<p>This class represents the data structure that is sent between the client and the server. It contains an ID, a source string, and a message string. The Pack method converts the Message object into a string representation, separating the fields with the | character.<\/p>\n<pre><code class=\"cs\">namespace amSocket;  public class Message {     public int id = 0;     public string src = \"\";     public string msg = \"\";        public Message(string packed)     {         var ar = packed.Split('|');         id = int.Parse(ar[0]);         src = ar[1];         msg = ar[2];     }        public string Pack() { return $\"{id}|{src}|{msg}\"; } } <\/code><\/pre>\n<h3>3.\u00a0Client.cs:<\/h3>\n<p>This class handles the client-side logic for sending data to the server. The Send method connects to the specified IP and port, converts the provided Message object to a string, and sends it to the server.<\/p>\n<pre><code class=\"cs\">using System.Text;  namespace amSocket;  public class Client : Config {     public static void Send(Message b)     {         _socket.Connect(_endPoint);          string message = b.Pack();         byte[] messageBytes = Encoding.UTF8.GetBytes(message);         _socket.Send(messageBytes);         _socket.Close();     } }<\/code><\/pre>\n<h3>4.\u00a0Server.cs:<\/h3>\n<p>This class handles the server-side logic for listening for incoming connections. The StartListen method binds the server socket to the specified IP and port, starts listening for connections, and accepts incoming connections asynchronously. When a connection is accepted, it receives data from the client and passes it to the provided callback as a Message object.<\/p>\n<pre><code class=\"cs\">using System.Net.Sockets; using System.Text;  namespace amSocket;  public class Server : Config {     static bool _needToClose = false;     public static void StartListen(Action&lt;Message> OnSocketMessage)     {         Task.Run(async () =>         {             try             {                 _socket.Bind(_endPoint);                 _socket.Listen(5);                  while (true)                 {                     var listener = _socket.Accept();                     var buffer = new byte[1_024];                     var received = await listener.ReceiveAsync(buffer, SocketFlags.None);                     var response = Encoding.UTF8.GetString(buffer, 0, received);                      Message b = new(response);                     OnSocketMessage(b);                      if (_needToClose) break;                 }             }             catch (Exception ex)             {                 Console.WriteLine(ex.ToString());             }         });     }     public static void StopListen()     {         _needToClose = true;         _socket.Close();     } }  <\/code><\/pre>\n<h3>Usage<\/h3>\n<p>To use this code, follow these steps:<\/p>\n<h3>1.\u00a0Start the Server:<\/h3>\n<p>Create an instance of the Server class and call the StartListen method, passing a callback function to handle incoming messages:<\/p>\n<pre><code class=\"cs\">Server.StartListen(OnSocketMessage);  void OnSocketMessage(Message b) {     Console.WriteLine($\"Received message: {b.msg} from {b.src} with ID {b.id}\"); }<\/code><\/pre>\n<h3>2.\u00a0Send Data from the Client:<\/h3>\n<p>Create an instance of the Client class and call the Send method with a Message object containing the data you want to send:<\/p>\n<pre><code class=\"cs\">Message b = new Message { id = 1, src = \"ClientApp\", msg = \"Hello, Server!\" }; Client.Send(b);<\/code><\/pre>\n<p>The server will receive the message and print it to the console:<\/p>\n<pre><code>Received message: Hello, Server! from ClientApp with ID 1<\/code><\/pre>\n<h3>Considerations<\/h3>\n<p>This implementation is a simple example and does not include error handling, concurrency management, or other advanced features that would be necessary for a production-ready application. Here are some considerations:<\/p>\n<ul>\n<li>\n<p><strong>Error Handling:<\/strong>\u00a0The code does not handle exceptions or errors that may occur during communication, such as network issues or invalid data.<\/p>\n<\/li>\n<li>\n<p><strong>Concurrency:<\/strong>\u00a0The server implementation uses a single thread to handle incoming connections. In a real-world scenario, you would need to handle multiple concurrent connections using techniques like asynchronous programming or threading.<\/p>\n<\/li>\n<li>\n<p><strong>Security:<\/strong>\u00a0The implementation does not include any security measures, such as encryption or authentication. In a production environment, you would need to ensure secure communication channels.<\/p>\n<\/li>\n<li>\n<p><strong>Scalability:<\/strong>\u00a0The current implementation is limited to a single server instance. For large-scale applications, you may need to consider load balancing, clustering, or other scalability techniques.<\/p>\n<\/li>\n<\/ul>\n<p>Despite its simplicity, this codebase serves as a good starting point for understanding the fundamentals of socket-based communication in C#. With proper enhancements and modifications, it can be adapted to meet the requirements of more complex and robust applications.<\/p>\n<\/p>\n<\/div>\n<\/div>\n<\/div>\n<p><!----><!----><\/div>\n<p><!----><!----><br \/> \u0441\u0441\u044b\u043b\u043a\u0430 \u043d\u0430 \u043e\u0440\u0438\u0433\u0438\u043d\u0430\u043b \u0441\u0442\u0430\u0442\u044c\u0438 <a href=\"https:\/\/habr.com\/ru\/articles\/809867\/\"> https:\/\/habr.com\/ru\/articles\/809867\/<\/a><br \/><\/br><\/br><\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[],"tags":[],"class_list":["post-374476","post","type-post","status-publish","format-standard","hentry"],"_links":{"self":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts\/374476","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=374476"}],"version-history":[{"count":0,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts\/374476\/revisions"}],"wp:attachment":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=374476"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=374476"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=374476"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}