Socket ma’lumotnomasi


ULASHISH

Soket obyekti

Socket klassi tarmoq ulanishlari orqali ma’lumotlarni o‘qish va yozish imkonini beruvchi dupleks oqimdir. U Node.js ning net modulida mijoz va server ulanishlari uchun ishlatiladi.

Soket masofaviy endpoint bilan TCP yoki IPC ulanishini ifodalaydi hamda ulanish lifecycle’ini (hayotiy siklini) boshqarish va ma’lumotlarni uzatish uchun metodlar va hodisalarni taqdim etadi.

Net modulni import qilish

// Import the net module
const net = require('net');

// Create a Socket
const socket = new net.Socket();
Misolni ishga tushirish »

Soket xususiyatlari

Xususiyat Tavsif
socket.bufferSize Yozish buferidagi hali yuborilmagan baytlar soni.
socket.bytesRead Soket tomonidan qabul qilingan baytlar soni.
socket.bytesWritten Soket tomonidan yuborilgan baytlar soni.
socket.connecting Soket ulanayotganini ko‘rsatuvchi boolean qiymat.
socket.destroyed Soket yo‘q qilinganini ko‘rsatuvchi boolean qiymat.
socket.localAddress Soketning mahalliy IP manzili.
socket.localPort Soketning mahalliy porti.
socket.remoteAddress Soketning masofaviy IP manzili.
socket.remoteFamily Masofaviy soketning IP oilasi (masalan, "IPv4" yoki "IPv6").
socket.remotePort Soketning masofaviy porti.


Soket usullari

Metod Tavsif
socket.connect(options[, connectListener]) Soketni belgilangan manzil va portga ulaydi. options port , host , localAddress , localPort va boshqalarni o‘z ichiga olishi mumkin.
socket.connect(path[, connectListener]) Soketni belgilangan IPC yo‘liga ulaydi.
socket.connect(port[, host][, connectListener]) Soketni belgilangan port va xostga ulaydi.
socket.destroy([error]) Soketni buzadi. Agar error berilgan bo‘lsa, u “xato” hodisasida chiqariladi.
socket.end([data][, encoding][, callback]) Ixtiyoriy data yuboradi va soketni yopadi, bu boshqa ma’lumotlar yuborilmasligini bildiradi.
socket.pause() Ma’lumotlarni o‘qishni to‘xtatib, kiruvchi ma’lumotlarni buferlash imkonini beradi.
socket.resume() socket.pause() chaqirilgandan so‘ng ma’lumotlarni o‘qishni davom ettiradi.
socket.setEncoding([encoding]) Soketni ma’lumotlarni belgilangan kodlashda kodlaydigan qilib sozlaydi (standart qiymat null, ya’ni Buffer obyektlari qaytariladi).
socket.setKeepAlive([enable][, initialDelay]) Millisekundlarda ixtiyoriy initialDelay bilan tirik saqlash funksiyasini yoqadi/o‘chiradi.
socket.setNoDelay([noDelay]) Nagle algoritmini yoqadi/o‘chiradi. true ga o‘rnatilganda, ma’lumotlar buferlangandan ko‘ra darhol yuboriladi.
socket.setTimeout(timeout[, callback]) Soket uchun vaqt tugashini o‘rnatadi, undan so‘ng hech qanday faoliyat bo‘lmasa, "tavt tugashi" hodisasi chiqariladi.
socket.write(data[, encoding][, callback]) Soketga ma’lumotlarni yozadi. Ma’lumotlar tozalangan bo‘lsa true yoki buferlangan bo‘lsa false qaytaradi.

Soket voqealari

Event Tavsif
'close' Soket to‘liq yopilganda chiqariladi. hadError argumenti soket xato tufayli yopilganligini bildiradi.
'connect' Soket ulanishi muvaffaqiyatli o‘rnatilganda ishga tushadi.
'data' Ma’lumot qabul qilinganda ishga tushadi. Argument — qabul qilingan ma’lumot (Buffer yoki String).
'drain' Yozish buferi bo‘shaganda ishga tushadi.
'end' Soketning boshqa uchi uzatish tugashini bildirganda chiqariladi.
'error' Xatolik yuzaga kelganda chiqariladi. "Yaqin" hodisasi to‘g‘ridan-to‘g‘ri ushbu tadbirdan keyin chiqariladi.
'lookup' Xost nomi aniqlangandan keyin, lekin ulanishdan oldin ishga tushadi. Qidiruv (lookup) haqidagi tafsilotlarni o‘z ichiga oladi.
'ready' Soket foydalanishga tayyor bo‘lganda chiqariladi.
'timeout' Agar soket ishlamay qolgan bo‘lsa, chiqariladi. Bu shunchaki bildirishnoma - soket avtomatik ravishda yopilmaydi.

TCP mijozini yaratish

Ushbu misol serverga ulanadigan TCP mijozini qanday yaratishni ko‘rsatadi:

const net = require('net');

// Create a new socket
const client = new net.Socket();

// Connect to a server
client.connect(8080, '127.0.0.1', () => {
  console.log('Connected to server');
  
  // Send data to the server
  client.write('Hello, server! From client.');
});

// Handle data received from the server
client.on('data', (data) => {
  console.log(`Received from server: ${data.toString()}`);
  
  // Close the connection after receiving a response
  client.end();
});

// Handle connection closure
client.on('close', () => {
  console.log('Connection closed');
});

// Handle errors
client.on('error', (err) => {
  console.error(`Error: ${err.message}`);
});
Misolni ishga tushirish »

TCP serverini yaratish

Ushbu misol soket ulanishlarini boshqaradigan TCP serverini yaratishni ko‘rsatadi:

const net = require('net');

// Create a TCP server
const server = net.createServer((socket) => {
  // 'socket' is the client connection - an instance of net.Socket
  
  console.log(`Client connected: ${socket.remoteAddress}:${socket.remotePort}`);
  
  // Set encoding
  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(`You said: ${data}`);
  });
  
  // Handle client disconnection
  socket.on('end', () => {
    console.log('Client disconnected');
  });
  
  // Handle socket errors
  socket.on('error', (err) => {
    console.error(`Socket error: ${err.message}`);
  });
  
  // Send a welcome message to the client
  socket.write('Welcome to the TCP server!\n');
});

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

// Handle server errors
server.on('error', (err) => {
  console.error(`Server error: ${err.message}`);
});
Misolni ishga tushirish »

Soket vaqti tugashi

Ushbu misol soket taym-autlarini qanday o‘rnatish va qayta ishlashni ko‘rsatadi:

const net = require('net');

// Create a server with timeouts
const server = net.createServer((socket) => {
  console.log('Client connected');
  
  // Set socket timeout to 10 seconds
  socket.setTimeout(10000);
  
  // Handle socket timeout
  socket.on('timeout', () => {
    console.log('Socket timeout - no activity for 10 seconds');
    socket.write('You have been inactive for too long. The connection will be closed.');
    socket.end();
  });
  
  // Handle data
  socket.on('data', (data) => {
    console.log(`Received: ${data.toString()}`);
    socket.write('Data received');
    
    // Each time we receive data, the timeout is reset
    console.log('Timeout timer reset');
  });
  
  // Handle socket closure
  socket.on('close', () => {
    console.log('Socket closed');
  });
  
  // Send welcome message
  socket.write('Welcome! This connection will timeout after 10 seconds of inactivity.\n');
});

// Start the server
const PORT = 8081;
server.listen(PORT, () => {
  console.log(`Timeout example server running on port ${PORT}`);
  
  // For testing: create a client that connects but doesn't send data
  const client = new net.Socket();
  client.connect(PORT, '127.0.0.1', () => {
    console.log('Test client connected');
    
    // We'll send a message after 5 seconds (before timeout)
    setTimeout(() => {
      client.write('Hello after 5 seconds');
    }, 5000);
    
    // We won't send anything else, so the connection should timeout
    // after another 10 seconds
  });
  
  client.on('data', (data) => {
    console.log(`Client received: ${data.toString()}`);
  });
  
  client.on('close', () => {
    console.log('Client disconnected');
  });
});
Misolni ishga tushirish »

Soket opsiyalari

Ushbu misol turli soket opsiyalarini qanday sozlashni ko‘rsatadi:

const net = require('net');

// Create a socket with options
const socket = new net.Socket();

// Configure socket options
socket.setKeepAlive(true, 1000); // Enable keep-alive with 1 second initial delay
socket.setNoDelay(true); // Disable Nagle's algorithm (no buffering)

// Connect to a server
socket.connect({
  port: 80,
  host: 'example.com',
  family: 4, // IPv4
  localAddress: '0.0.0.0', // Local interface to bind to
  localPort: 8000 // Local port to bind to
}, () => {
  console.log('Connected with options');
  
  // Display socket information
  console.log(`Local address: ${socket.localAddress}:${socket.localPort}`);
  console.log(`Remote address: ${socket.remoteAddress}:${socket.remotePort}`);
  console.log(`Remote family: ${socket.remoteFamily}`);
  
  // Send a simple HTTP request
  socket.write('GET / HTTP/1.1\r\n');
  socket.write('Host: example.com\r\n');
  socket.write('Connection: close\r\n');
  socket.write('\r\n');
});

// Handle data
let responseData = '';
socket.on('data', (data) => {
  const chunk = data.toString();
  responseData += chunk;
  
  // Show first line of the response
  if (responseData.includes('\r\n') && !socket.firstLineShown) {
    const firstLine = responseData.split('\r\n')[0];
    console.log(`First line of response: ${firstLine}`);
    socket.firstLineShown = true;
  }
});

// Handle end of data
socket.on('end', () => {
  console.log('Response complete');
  console.log(`Total bytes received: ${socket.bytesRead}`);
  console.log(`Total bytes sent: ${socket.bytesWritten}`);
});

// Handle errors
socket.on('error', (err) => {
  console.error(`Socket error: ${err.message}`);
});
Misolni ishga tushirish »

Soket buferlari bilan ishlash

Ushbu misol soketni buferlashni va "drenaj" hodisasini ko‘rsatadi:

const net = require('net');

// Create server to demonstrate buffer handling
const server = net.createServer((socket) => {
  console.log('Client connected');
  
  // Make buffer small to demonstrate filling it faster
  socket.bufferSize = 1024; // Note: This doesn't actually limit the buffer size
  
  // Send a slow response to the client to demonstrate buffering
  socket.on('data', (data) => {
    console.log(`Received data: ${data.toString().trim()}`);
    console.log('Sending large response...');
    
    // Function to write data until buffer is full
    const writeUntilBufferFull = () => {
      // Generate some data to send
      const chunk = 'x'.repeat(1024);
      
      // Keep writing until the buffer is full (write returns false)
      let i = 0;
      while (i < 100) {
        const canContinue = socket.write(`Chunk ${i}: ${chunk}\n`);
        console.log(`Wrote chunk ${i}, buffer full? ${!canContinue}`);
        
        // If the buffer is full, wait for it to drain
        if (!canContinue) {
          console.log(`Buffer is full after ${i} writes. Current buffer size: ${socket.bufferSize} bytes`);
          // Stop writing and wait for the 'drain' event
          socket.once('drain', () => {
            console.log('Buffer drained, resuming writes');
            writeUntilBufferFull();
          });
          return;
        }
        i++;
      }
      
      // All chunks written
      console.log('All data sent');
      socket.end('\nTransmission complete');
    };
    
    // Start the writing process
    writeUntilBufferFull();
  });
  
  socket.on('end', () => {
    console.log('Client disconnected');
  });
  
  socket.on('error', (err) => {
    console.error(`Socket error: ${err.message}`);
  });
  
  socket.write('Send any message to receive a large response\n');
});

// Start the server
const PORT = 8082;
server.listen(PORT, () => {
  console.log(`Buffer demonstration server running on port ${PORT}`);
  
  // For demonstration, create a client that connects and sends a message
  const client = new net.Socket();
  
  client.connect(PORT, '127.0.0.1', () => {
    console.log('Test client connected');
    
    // Send a message after 1 second
    setTimeout(() => {
      client.write('Please send me a large response');
    }, 1000);
  });
  
  let receivedData = 0;
  client.on('data', (data) => {
    receivedData += data.length;
    console.log(`Client received ${data.length} bytes, total: ${receivedData}`);
  });
  
  client.on('end', () => {
    console.log(`Client disconnected after receiving ${receivedData} bytes`);
    process.exit(0);
  });
  
  client.on('error', (err) => {
    console.error(`Client error: ${err.message}`);
  });
});
Misolni ishga tushirish »

IPC soket aloqasi

Ushbu misol Unix domen soketlaridan foydalangan holda Inter-Process Communication (IPC) ni ko‘rsatadi:

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

// IPC path - depending on OS
const socketPath = process.platform === 'win32'
  ? path.join('\\\\?\\pipe', process.cwd(), 'ipc-demo.sock')
  : path.join(process.cwd(), 'ipc-demo.sock');

// Remove existing socket file if it exists (Unix only)
if (process.platform !== 'win32' && fs.existsSync(socketPath)) {
  fs.unlinkSync(socketPath);
}

// Create IPC server
const server = net.createServer((socket) => {
  console.log('Client connected to IPC socket');
  
  socket.on('data', (data) => {
    const message = data.toString().trim();
    console.log(`Server received: ${message}`);
    
    // Echo back
    socket.write(`Echo: ${message}`);
  });
  
  socket.on('end', () => {
    console.log('Client disconnected from IPC socket');
  });
  
  socket.write('Connected to IPC server\n');
});

// Handle server errors
server.on('error', (err) => {
  console.error(`IPC server error: ${err.message}`);
});

// Start IPC server
server.listen(socketPath, () => {
  console.log(`IPC server listening on ${socketPath}`);
  
  // Create client that connects to the IPC socket
  const client = new net.Socket();
  
  client.on('data', (data) => {
    console.log(`Client received: ${data.toString().trim()}`);
  });
  
  client.on('end', () => {
    console.log('Disconnected from IPC server');
  });
  
  client.on('error', (err) => {
    console.error(`IPC client error: ${err.message}`);
  });
  
  // Connect to the IPC server
  client.connect(socketPath, () => {
    console.log('Connected to IPC server');
    client.write('Hello via IPC socket');
    
    // Send multiple messages
    setTimeout(() => {
      client.write('Message 1');
    }, 1000);
    
    setTimeout(() => {
      client.write('Message 2');
      client.end(); // Close after sending the last message
    }, 2000);
  });
});

// Cleanup on exit
process.on('exit', () => {
  if (process.platform !== 'win32' && fs.existsSync(socketPath)) {
    fs.unlinkSync(socketPath);
  }
});

// Handle Ctrl+C
process.on('SIGINT', () => {
  console.log('Shutting down...');
  process.exit(0);
});
Misolni ishga tushirish »

Yarim yopiq soketlar

Ushbu misol yarim yopiq ulanishlarni ko‘rsatadi, bu yerda bir tomon yozish oqimini tugatgan, lekin hali ham ma’lumotlarni qabul qila oladi:

const net = require('net');

// Create server
const server = net.createServer((socket) => {
  console.log('Client connected');
  
  // Send initial message
  socket.write('Welcome to the half-close demonstration server\n');
  
  // Handle data from client
  socket.on('data', (data) => {
    console.log(`Server received: ${data.toString().trim()}`);
  });
  
  // Handle socket end (client ended their write stream)
  socket.on('end', () => {
    console.log('Client ended their write stream (half-closed)');
    
    // We can still write to the client after they've ended their write stream
    socket.write('You have ended your side of the connection, but I can still talk to you.');
    
    // Close our side after a delay
    setTimeout(() => {
      console.log('Server now closing its write stream');
      socket.end('Goodbye! Closing my side of the connection now.');
    }, 8080);
  });
  
  // Handle complete socket closure
  socket.on('close', (hadError) => {
    console.log(`Socket fully closed. Had error: ${hadError}`);
  });
  
  socket.on('error', (err) => {
    console.error(`Socket error: ${err.message}`);
  });
});

// Start server
const PORT = 8083;
server.listen(PORT, () => {
  console.log(`Half-close demonstration server running on port ${PORT}`);
  
  // Create a client for demonstration
  const client = new net.Socket();
  
  client.connect(PORT, '127.0.0.1', () => {
    console.log('Client connected');
    
    // Send some data
    client.write('Hello from client');
    
    // After a delay, end the client write stream (half-close)
    setTimeout(() => {
      console.log('Client ending its write stream (half-closing)');
      client.end();
      
      // We can't write anymore, but we can still receive data
      console.log('Client waiting to receive more data...');
    }, 2000);
  });
  
  // Handle data from server
  client.on('data', (data) => {
    console.log(`Client received: ${data.toString().trim()}`);
  });
  
  // Handle server closing its write stream
  client.on('end', () => {
    console.log('Server ended its write stream, connection fully closed');
  });
  
  // Handle complete connection closure
  client.on('close', (hadError) => {
    console.log(`Client connection fully closed. Had error: ${hadError}`);
  });
  
  client.on('error', (err) => {
    console.error(`Client error: ${err.message}`);
  });
});
Misolni ishga tushirish »

Soket dasturlash uchun eng yaxshi amaliyotlar

Node.js-da soketlar bilan ishlashda quyidagi eng yaxshi amaliyotlarni ko‘rib chiqing:

  1. Xatoni qayta ishlash: Ishlamaydigan istisnolarning oldini olish uchun har doim "xato" hodisasini boshqaring.
  2. Resurslarni tozalash: Xotira oqib chiqmasligi uchun soketlar to‘g‘ri yopilganligiga ishonch hosil qiling.
  3. Buferni boshqarish: socket.bufferSize ni kuzating va katta hajmdagi ma’lumotlarni jo‘natishda xotira bilan bog‘liq muammolarni oldini olish uchun “drain” hodisasidan foydalaning.
  4. Vaqt tugashi: eskirgan ulanishlarni qayta ishlash uchun socket.setTimeout() bilan mos vaqtni o‘rnating.
  5. Keep-alive: Uzoq davom etadigan ulanishlar uchun tirik qolish sozlamalarini sozlang.
  6. Ma’lumotlarni kodlash: socket.setEncoding() bilan mos kodlashni o‘rnating yoki ikkilik ma’lumotlarni mos ravishda ishlating.
  7. Xavfsizlik: Xavfsiz aloqa uchun TCP soketlari o‘rniga TLS/SSL modulidan ( tls ) foydalaning.
  8. Orqaga bosim: Orqa bosimni boshqarish uchun socket.write() qaytariladigan qiymatiga e’tibor bering.

W3Schools Pathfinder

Yutuqlaringizni kuzating – bu bepul!