Net moduli


ULASHISH

Net moduliga kirish

Net moduli Node.js ning asosiy tarmoq modullaridan biri bo‘lib, TCP serverlari va mijozlarini yaratish imkonini beradi. TCP (Transmission Control Protocol) - tarmoqqa ulangan qurilmalarda ishlaydigan ilovalar o‘rtasida baytlar oqimini ishonchli, tartiblangan va xato tekshirilgan yetkazib berish.

Net moduli ustiga qurilgan HTTP modulidan farqli o‘laroq, Net moduli sizga aloqa protokoli ustidan ko‘proq nazorat qilish imkonini beruvchi quyi darajadagi tarmoq imkoniyatlarini taqdim etadi.

Eslatma: Net moduli sizga maxsus TCP protokoli kerak bo‘lgan yoki TCP tepasida o‘z dastur darajasidagi protokolingizni joriy qilmoqchi bo‘lgan stsenariylar uchun eng mos keladi.


Net modulni import qilish

Net modulidan foydalanish uchun uni Node.js ilovangizga import qilishingiz kerak:

const net = require('net');

TCP serverini yaratish

Net moduli ulanishlarni tinglaydigan TCP serverini yaratishni osonlashtiradi:

const net = require('net');

// Create a TCP server
const server = net.createServer((socket) => {
  console.log('Client connected');
  
  // Set encoding to utf8 so we receive strings instead of Buffer objects
  socket.setEncoding('utf8');
  
  // Handle data from client
  socket.on('data', (data) => {
    console.log(`Received from client: ${data}`);
    
    // Echo the data back to the client
    socket.write(`Echo: ${data}`);
  });
  
  // Handle client disconnection
  socket.on('end', () => {
    console.log('Client disconnected');
  });
  
  // Handle errors
  socket.on('error', (err) => {
    console.error('Socket error:', err);
  });
  
  // Send a welcome message to the client
  socket.write('Welcome to the TCP server!\r\n');
});

// Start the server and listen on port 8080
server.listen(8080, () => {
  console.log('TCP Server running on port 8080');
});

Ushbu misolda:

  • net.createServer() yangi TCP serverini yaratadi
  • callback qilish funksiyasi mijoz ulanganda chaqiriladi
  • socket obyekti mijoz bilan aloqani ifodalaydi
  • Biz data , end va error hodisalari uchun hodisalarni qayta ishlash vositalarini o‘rnatdik
  • server.listen(8080) 8080 portida serverni ishga tushiradi


TCP mijozini yaratish

TCP serveriga ulanish uchun TCP mijozini ham yaratishingiz mumkin:

const net = require('net');

// Create a TCP client
const client = net.createConnection({ port: 8080 }, () => {
  console.log('Connected to server');
  
  // Send a message to the server
  client.write('Hello from client!');
});

// Set encoding
client.setEncoding('utf8');

// Handle data from server
client.on('data', (data) => {
  console.log(`Received from server: ${data}`);
  
  // Send another message
  client.write('More data from client');
});

// Handle connection end
client.on('end', () => {
  console.log('Disconnected from server');
});

// Handle errors
client.on('error', (err) => {
  console.error('Connection error:', err);
});

Ushbu misolda:

  • net.createConnection() TCP serveriga mijoz ulanishini yaratadi
  • Ulanish uchun portni (va ixtiyoriy ravishda xostni) ko‘rsatamiz
  • callback qilish funksiyasi ulanish o‘rnatilganda chaqiriladi
  • Biz data , end va error hodisalari uchun hodisalarni qayta ishlash vositalarini o‘rnatdik

Eslatma: Mijoz va serverni birgalikda sinab ko‘rish uchun server skriptini bitta terminalda va mijoz skriptini boshqa terminalda ishga tushiring.


Soket xususiyatlari va usullari

Server ulanishiga callback funksiyasi qilish uchun taqdim etilgan va createConnection() tomonidan qaytarilgan Socket obyekti juda ko‘p foydali xususiyatlar va usullarga ega:

Xususiyat/usul Tavsif
socket.write(data[, encoding][, callback]) Ixtiyoriy ravishda belgilangan kodlash bilan soketga ma’lumotlarni yozadi
socket.end([data][, encoding][, callback]) Barcha ma’lumotlar yozilgan va yuvilgandan keyin soketni yopadi
socket.setEncoding(encoding) Soketga olingan ma’lumotlar uchun kodlashni o‘rnatadi
socket.setTimeout(timeout[, callback]) Belgilangan millisekundlik harakatsizlikdan keyin soketni vaqt tugashiga o‘rnatadi
socket.setKeepAlive([enable][, initialDelay]) Jonli saqlash funksiyasini yoqadi/o‘chiradi
socket.address() Ulanish manzili, oilasi va porti bilan obyektni qaytaradi
socket.remoteAddress Masofaviy IP-manzil string sifatida
socket.remotePort Raqam sifatida masofaviy port
socket.localAddress Server tinglayotgan mahalliy IP manzil
socket.localPort Server tinglayotgan mahalliy port
socket.bytesRead Qabul qilingan baytlar soni
socket.bytesWritten Yuborilgan baytlar soni

Server xususiyatlari va usullari

createServer() tomonidan qaytarilgan Server obyekti quyidagi foydali xususiyatlar va usullarga ega:

Xususiyat/usul Tavsif
server.listen(port[, hostname][, backlog][, callback]) Server ulanishlarni tinglashni boshlaydi
server.close([callback]) Serverning yangi ulanishlarni qabul qilishini to‘xtatadi
server.address() Server manzili ma’lumotlari bilan obyektni qaytaradi
server.maxConnections Ulanish soni undan oshib ketganda ulanishlarni rad etish uchun ushbu xususiyatni sozlang
server.connections Bir vaqtning o‘zida ulanishlar soni
server.listening Server tinglayotganligini ko‘rsatadigan mantiqiy

Chat serverini yaratish

Keling, barcha ulangan mijozlarga xabarlarni uzatadigan oddiy chat serverini yarataylik:

const net = require('net');

// Store all client connections
const clients = [];

// Create a chat server
const server = net.createServer((socket) => {
  // Generate a client ID
  const clientId = `${socket.remoteAddress}:${socket.remotePort}`;
  console.log(`Client connected: ${clientId}`);
  
  // Set encoding
  socket.setEncoding('utf8');
  
  // Add client to the list
  clients.push(socket);
  
  // Send welcome message
  socket.write(`Welcome to the chat server! There are ${clients.length} users online.\r\n`);
  
  // Broadcast message to all clients except the sender
  function broadcast(message, sender) {
    clients.forEach(client => {
      if (client !== sender) {
        client.write(message);
      }
    });
  }
  
  // Notify all clients about the new connection
  broadcast(`User ${clientId} joined the chat.\r\n`, socket);
  
  // Handle client messages
  socket.on('data', (data) => {
    console.log(`${clientId}: ${data.trim()}`);
    
    // Broadcast the message to all other clients
    broadcast(`${clientId}: ${data}`, socket);
  });
  
  // Handle client disconnection
  socket.on('end', () => {
    console.log(`Client disconnected: ${clientId}`);
    
    // Remove client from the list
    const index = clients.indexOf(socket);
    if (index !== -1) {
      clients.splice(index, 1);
    }
    
    // Notify all clients about the disconnection
    broadcast(`User ${clientId} left the chat.\r\n`, null);
  });
  
  // Handle errors
  socket.on('error', (err) => {
    console.error(`Socket error from ${clientId}:`, err);
  });
});

// Start the server
const PORT = 8080;
server.listen(PORT, () => {
  console.log(`Chat server running on port ${PORT}`);
});

// Handle server errors
server.on('error', (err) => {
  console.error('Server error:', err);
});

Ushbu chat serveriga ulanish uchun siz TCP mijozi yoki telnet kabi terminal vositasidan foydalanishingiz mumkin:

telnet localhost 8080

Bundan tashqari, Net moduli yordamida maxsus chat mijozini yaratishingiz mumkin:

const net = require('net');
const readline = require('readline');

// Create interface for reading from the terminal
const rl = readline.createInterface({
  input: process.stdin,
  output: process.stdout
});

// Create a client connection
const client = net.createConnection({ port: 8080 }, () => {
  console.log('Connected to chat server');
  console.log('Type a message and press Enter to send');
  
  // Start reading user input
  rl.prompt();
});

// Set encoding
client.setEncoding('utf8');

// Handle data from server
client.on('data', (data) => {
  // Move cursor to beginning of line and clear it
  process.stdout.write('\r\x1b[K');
  
  // Print the server message
  console.log(data.trim());
  
  // Re-display the prompt
  rl.prompt();
});

// Handle connection end
client.on('end', () => {
  console.log('Disconnected from server');
  rl.close();
  process.exit(0);
});

// Handle errors
client.on('error', (err) => {
  console.error('Connection error:', err);
  rl.close();
  process.exit(1);
});

// Handle user input
rl.on('line', (input) => {
  // Send the user input to the server
  client.write(input);
  rl.prompt();
});

// Close the connection when the user exits
rl.on('close', () => {
  console.log('Exiting chat...');
  client.end();
});

Oddiy protokol yaratish

Net modulidan foydalanishning afzalliklaridan biri bu o‘z amaliy protokollaringizni yaratish imkoniyatidir. Keling, oddiy JSON-ga asoslangan protokolni yarataylik:

const net = require('net');

// Create a server that supports a JSON-based protocol
const server = net.createServer((socket) => {
  console.log('Client connected');
  
  // Buffer for incoming data
  let buffer = '';
  
  // Handle data
  socket.on('data', (data) => {
    // Add the new data to our buffer
    buffer += data.toString();
    
    // Process complete messages
    let boundary = buffer.indexOf('\n');
    while (boundary !== -1) {
      // Extract the complete message
      const message = buffer.substring(0, boundary);
      buffer = buffer.substring(boundary + 1);
      
      // Process the message
      try {
        const parsedMessage = JSON.parse(message);
        console.log('Received message:', parsedMessage);
        
        // Handle different message types
        switch (parsedMessage.type) {
          case 'greeting':
            socket.write(JSON.stringify({
              type: 'welcome',
              message: `Hello, ${parsedMessage.name}!`,
              timestamp: Date.now()
            }) + '\n');
            break;
            
          case 'query':
            socket.write(JSON.stringify({
              type: 'response',
              queryId: parsedMessage.queryId,
              result: handleQuery(parsedMessage.query),
              timestamp: Date.now()
            }) + '\n');
            break;
            
          default:
            socket.write(JSON.stringify({
              type: 'error',
              message: 'Unknown message type',
              timestamp: Date.now()
            }) + '\n');
        }
      } catch (err) {
        console.error('Error processing message:', err);
        socket.write(JSON.stringify({
          type: 'error',
          message: 'Invalid JSON format',
          timestamp: Date.now()
        }) + '\n');
      }
      
      // Look for the next message
      boundary = buffer.indexOf('\n');
    }
  });
  
  // Handle disconnection
  socket.on('end', () => {
    console.log('Client disconnected');
  });
  
  // Handle errors
  socket.on('error', (err) => {
    console.error('Socket error:', err);
  });
});

// Simple function to handle queries
function handleQuery(query) {
  if (query === 'time') {
    return { time: new Date().toISOString() };
  } else if (query === 'stats') {
    return {
      uptime: process.uptime(),
      memory: process.memoryUsage(),
      platform: process.platform
    };
  } else {
    return { error: 'Unknown query' };
  }
}

// Start the server
const PORT = 8080;
server.listen(PORT, () => {
  console.log(`JSON protocol server running on port ${PORT}`);
});

Va bu protokoldan foydalanadigan mijoz:

const net = require('net');

// Connect to the server
const client = net.createConnection({ port: 8080 }, () => {
  console.log('Connected to server');
  
  // Send a greeting
  send({
    type: 'greeting',
    name: 'Client'
  });
  
  // Send a query
  send({
    type: 'query',
    queryId: 1,
    query: 'time'
  });
  
  // Send another query
  setTimeout(() => {
    send({
      type: 'query',
      queryId: 2,
      query: 'stats'
    });
  }, 1000);
});

// Buffer for incoming data
let buffer = '';

// Handle data from server
client.on('data', (data) => {
  // Add the new data to our buffer
  buffer += data.toString();
  
  // Process complete messages
  let boundary = buffer.indexOf('\n');
  while (boundary !== -1) {
    // Extract the complete message
    const message = buffer.substring(0, boundary);
    buffer = buffer.substring(boundary + 1);
    
    // Process the message
    try {
      const parsedMessage = JSON.parse(message);
      console.log('Received from server:', parsedMessage);
    } catch (err) {
      console.error('Error parsing message:', err);
    }
    
    // Look for the next message
    boundary = buffer.indexOf('\n');
  }
});

// Helper function to send messages
function send(message) {
  const jsonString = JSON.stringify(message) + '\n';
  console.log('Sending:', message);
  client.write(jsonString);
}

// Handle connection end
client.on('end', () => {
  console.log('Disconnected from server');
});

// Handle errors
client.on('error', (err) => {
  console.error('Connection error:', err);
});

// Close the connection after some time
setTimeout(() => {
  console.log('Closing connection');
  client.end();
}, 5000);

Eslatma: Ushbu protokolda biz xabarlarni ketma-ketlashtirish uchun JSON va xabar chegaralari sifatida yangi qator belgilaridan (\n) foydalanamiz. Bu xabarlarni tahlil qilishni osonlashtiradi va har xil xabar turlari va ma’lumotlarni (payload) olish imkonini beradi.


Soket vaqtlari

Faol bo‘lmagan ulanishlarni boshqarish uchun siz soketda kutish vaqtini o‘rnatishingiz mumkin:

const net = require('net');

const server = net.createServer((socket) => {
  console.log('Client connected');
  
  // Set a timeout of 10 seconds
  socket.setTimeout(10000);
  
  // Handle timeout
  socket.on('timeout', () => {
    console.log('Socket timeout');
    socket.write('You have been inactive for too long. Disconnecting...\r\n');
    socket.end();
  });
  
  // Handle data
  socket.on('data', (data) => {
    console.log(`Received: ${data.toString().trim()}`);
    socket.write(`Echo: ${data}`);
  });
  
  // Handle disconnection
  socket.on('end', () => {
    console.log('Client disconnected');
  });
});

server.listen(8080, () => {
  console.log('Server with timeout running on port 8080');
});

IPC (Inter-Process Communication, jarayonlararo aloqa) bilan ishlash

Net moduli, shuningdek, Windowsda Unix domen soketlari yoki named pipes (nomlangan payplar) yordamida IPC (jarayonlararo aloqa) serverlari va mijozlarini yaratishi mumkin:

const net = require('net');
const path = require('path');

// Define the path for the IPC socket
const socketPath = path.join(__dirname, 'ipc-socket');

// Create an IPC server
const server = net.createServer((socket) => {
  console.log('Client connected to IPC server');
  
  socket.on('data', (data) => {
    console.log(`Received via IPC: ${data.toString().trim()}`);
    socket.write(`Echo: ${data}`);
  });
  
  socket.on('end', () => {
    console.log('Client disconnected from IPC server');
  });
});

// Start the IPC server
server.listen(socketPath, () => {
  console.log(`IPC server running at ${socketPath}`);
});

// Clean up the socket file when the server closes
server.on('close', () => {
  console.log('Cleaning up socket file');
  require('fs').unlinkSync(socketPath);
});

// Handle process termination
process.on('SIGINT', () => {
  server.close(() => {
    console.log('IPC server closed');
    process.exit(0);
  });
});

Va bu yerda IPC mijozi:

const net = require('net');
const path = require('path');

// Define the path for the IPC socket
const socketPath = path.join(__dirname, 'ipc-socket');

// Create an IPC client
const client = net.createConnection({ path: socketPath }, () => {
  console.log('Connected to IPC server');
  client.write('Hello from IPC client!');
});

client.on('data', (data) => {
  console.log(`Received from IPC server: ${data.toString().trim()}`);
  client.end();
});

client.on('end', () => {
  console.log('Disconnected from IPC server');
});

client.on('error', (err) => {
  console.error('Connection error:', err);
});

Eslatma: Unix domen soketlari yoki named pipes (nomlangan payplar) foydalangan holda IPC ulanishlari odatda TCP ulanishlariga qaraganda tezroq va xavfsizroqdir, chunki ular tarmoq stackidan foydalanmaydi va mahalliy mashina bilan cheklangan.


Eng yaxshi amaliyotlar

  1. Xatolarni qayta ishlash: Ilovangiz ishdan chiqishiga yo‘l qo‘ymaslik uchun har doim soketdagi xatolarni ko‘rib chiqing.
  2. Vaqt tugashi: Faol bo‘lmagan ulanishlarni qayta ishlash va resurslarning sizib chiqishini oldini olish uchun taym-autlarni qo‘llang.
  3. Keep-Alive: Uzilishlarni aniqlash uchun uzoq muddatli ulanishlar uchun keep-alive-dan foydalaning.
  4. Buferlash: Qisman xabarlarni qayta ishlash uchun protokolingiz uchun tegishli xabar ramkalarini va buferlashni amalga oshiring.
  5. Ulanish cheklovlari: Serveringizni haddan tashqari oshirib yubormaslik uchun server.maxConnections belgilang.
  6. Graceful O‘chirish: Resurslarni chiqarish uchun serverlarni o‘chirishda to‘g‘ri tozalashni amalga oshiring.
  7. Ikkilik ma’lumotlar: Kodlash bilan bog‘liq muammolarni oldini olish uchun ikkilik ma’lumotlarni uzatish uchun stringlar o‘rniga Buffer obyektlaridan foydalaning.
  8. Orqaga bosim: Mijoz davom eta olmaganida, orqa bosimni boshqarish uchun socket.write() qaytish qiymatini tekshiring.

Net modul va HTTP moduli

Xususiyat Net moduli HTTP moduli
Protokol Raw TCP/IP HTTP protokoli
Xabar formati Maxsus (uni o‘zingiz belgilaysiz) HTTP so‘rovi/javobi
Abstraksiya darajasi Pastki daraja, ko‘proq nazorat Yuqori darajali, foydalanish osonroq
Foydalanish holati Maxsus protokollar, ishlash uchun muhim ilovalar Veb-ilovalar, REST API

Net modulidan quyidagi hollarda foydalaning:

  • Maxsus protokolni amalga oshirishingiz kerak
  • Siz aloqa ustidan maksimal nazoratni xohlaysiz
  • Ishlash uchun optimallashtirish kerak
  • Siz HTTP bo‘lmagan TCP serverini qurmoqdasiz (chat, o‘yin va h.k.)

HTTP modulidan quyidagi hollarda foydalaning:

  • Siz veb-server yoki API qurmoqdasiz
  • Sizga HTTP-ga xos xususiyatlar, masalan, so‘rovni yo‘naltirish, sarlavhalar va boshqalar kerak.
  • Siz Express kabi yuqori darajadagi veb-frameworklardan foydalanmoqchisiz

Xulosa

Node.js Net moduli TCP serverlari va mijozlarini yaratish uchun kuchli vositalarni taqdim etadi. U taklif qiladi:

  • Maxsus protokollar uchun past darajadagi soketga kirish
  • Ulanishlarni boshqarish uchun asinxron, hodisalarga asoslangan API
  • TCP/IP va IPC aloqalarini qo‘llab-quvvatlash
  • Yuqori darajadagi protokollar uchun qurilish bloklari

HTTP kabi yuqori darajadagi modullarga qaraganda ko‘proq qo‘lda ishlashni talab qilsa-da, Net moduli sizga ilovangiz uchun kerakli protokolni amalga oshirish uchun moslashuvchanlikni beradi.

Eslatma: Har doim netstat , ss yoki lsof kabi vositalar yordamida TCP serveringiz unumdorlikni nazorat qilib boring.




W3Schools Pathfinder

Yutuqlaringizni kuzating – bu bepul!