ソケットの接続とデータ転送の基礎

socket-connection-data-transfer

ソケット通信は、ネットワークプログラミングの基本であり、TCP(Transmission Control Protocol)とUDP(User Datagram Protocol)の2つの主要なプロトコルがあります。TCPは信頼性が高く、順序を保証する接続指向のプロトコルで、UDPは接続を必要としない軽量プロトコルです。この2つのプロトコルを理解することは、ネットワークアプリケーションを作成する上で重要です。この記事では、TCPおよびUDPのサーバーとクライアントのソケット通信のサンプルコードをPython、C#、C++、Java、JavaScriptで紹介します。

目次

基本概念の説明

TCP (Transmission Control Protocol)

信頼性が高いプロトコルで、送受信データの順序や誤りのチェックを行います。通信にはコネクションの確立が必要で、データはストリームとしてやり取りされます。

UDP (User Datagram Protocol)

軽量なプロトコルで、コネクションを確立せずにデータを送信します。信頼性や順序の保証がありませんが、リアルタイム性が求められる通信(ビデオストリーミングなど)に適しています。

各言語でのサンプルコード

Python: TCP と UDP サーバーとクライアント

TCP サーバーとクライアント


# Python TCP サーバープログラム
import socket

server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server_socket.bind(('localhost', 12345))
server_socket.listen(1)
print("Waiting for a TCP connection...")

conn, addr = server_socket.accept()
print(f"Connection from {addr}")

data = conn.recv(1024).decode()
print(f"Received data: {data}")

conn.send("Hello from TCP server".encode())
conn.close()

# Python TCP クライアントプログラム
import socket

client_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
client_socket.connect(('localhost', 12345))

client_socket.send("Hello from TCP client".encode())
response = client_socket.recv(1024).decode()
print(f"Received from server: {response}")

client_socket.close()

UDP サーバーとクライアント


# Python UDP サーバープログラム
import socket

server_socket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
server_socket.bind(('localhost', 12345))
print("UDP server is ready")

while True:
    data, addr = server_socket.recvfrom(1024)
    print(f"Received message: {data.decode()} from {addr}")
    server_socket.sendto("Hello from UDP server".encode(), addr)

# Python UDP クライアントプログラム
import socket

client_socket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
client_socket.sendto("Hello from UDP client".encode(), ('localhost', 12345))

data, addr = client_socket.recvfrom(1024)
print(f"Received from server: {data.decode()}")
client_socket.close()

C#: TCP と UDP サーバーとクライアント

TCP サーバーとクライアント


// C# TCP サーバープログラム
using System;
using System.Net;
using System.Net.Sockets;
using System.Text;

class TcpServer
{
    static void Main()
    {
        TcpListener server = new TcpListener(IPAddress.Parse("127.0.0.1"), 12345);
        server.Start();
        Console.WriteLine("Waiting for a TCP connection...");

        TcpClient client = server.AcceptTcpClient();
        NetworkStream stream = client.GetStream();

        byte[] buffer = new byte[1024];
        int bytesRead = stream.Read(buffer, 0, buffer.Length);
        string data = Encoding.ASCII.GetString(buffer, 0, bytesRead);
        Console.WriteLine($"Received data: {data}");

        byte[] response = Encoding.ASCII.GetBytes("Hello from TCP server");
        stream.Write(response, 0, response.Length);
        client.Close();
        server.Stop();
    }
}

// C# TCP クライアントプログラム
using System;
using System.Net.Sockets;
using System.Text;

class TcpClientApp
{
    static void Main()
    {
        TcpClient client = new TcpClient("127.0.0.1", 12345);
        NetworkStream stream = client.GetStream();

        byte[] data = Encoding.ASCII.GetBytes("Hello from TCP client");
        stream.Write(data, 0, data.Length);

        byte[] buffer = new byte[1024];
        int bytesRead = stream.Read(buffer, 0, buffer.Length);
        string response = Encoding.ASCII.GetString(buffer, 0, bytesRead);
        Console.WriteLine($"Received from server: {response}");

        client.Close();
    }
}

UDP サーバーとクライアント


// C# UDP サーバープログラム
using System;
using System.Net;
using System.Net.Sockets;
using System.Text;

class UdpServer
{
    static void Main()
    {
        UdpClient server = new UdpClient(12345);
        IPEndPoint clientEndpoint = new IPEndPoint(IPAddress.Any, 0);
        Console.WriteLine("UDP server is ready");

        while (true)
        {
            byte[] data = server.Receive(ref clientEndpoint);
            Console.WriteLine($"Received message: {Encoding.ASCII.GetString(data)} from {clientEndpoint}");
            byte[] response = Encoding.ASCII.GetBytes("Hello from UDP server");
            server.Send(response, response.Length, clientEndpoint);
        }
    }
}

// C# UDP クライアントプログラム
using System;
using System.Net;
using System.Net.Sockets;
using System.Text;

class UdpClientApp
{
    static void Main()
    {
        UdpClient client = new UdpClient();
        byte[] data = Encoding.ASCII.GetBytes("Hello from UDP client");
        client.Send(data, data.Length, "localhost", 12345);

        IPEndPoint serverEndpoint = new IPEndPoint(IPAddress.Any, 0);
        byte[] response = client.Receive(ref serverEndpoint);
        Console.WriteLine($"Received from server: {Encoding.ASCII.GetString(response)}");
        client.Close();
    }
}

C++: TCP と UDP サーバーとクライアント

TCP サーバーとクライアント


// C++ TCP サーバープログラム
#include <iostream>
#include <string>
#include <sys/socket.h>
#include <netinet/in.h>
#include <unistd.h>

int main() {
    int server_fd = socket(AF_INET, SOCK_STREAM, 0);
    sockaddr_in address = {AF_INET, htons(12345), INADDR_ANY};

    bind(server_fd, (sockaddr*)&address, sizeof(address));
    listen(server_fd, 1);
    std::cout << "Waiting for a TCP connection..." << std::endl;

    int client_fd = accept(server_fd, nullptr, nullptr);
    char buffer[1024] = {0};
    read(client_fd, buffer, 1024);
    std::cout << "Received data: " << buffer << std::endl;

    std::string response = "Hello from TCP server";
    send(client_fd, response.c_str(), response.length(), 0);
    close(client_fd);
    close(server_fd);
}

// C++ TCP クライアントプログラム
#include <iostream>
#include <string>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <unistd.h>

int main() {
    int client_fd = socket(AF_INET, SOCK_STREAM, 0);
    sockaddr_in server_address = {AF_INET, htons(12345), inet_addr("127.0.0.1")};

    connect(client_fd, (sockaddr*)&server_address, sizeof(server_address));

    std::string message = "Hello from TCP client";
    send(client_fd, message.c_str(), message.length(), 0);

    char buffer[1024] = {0};
    read(client_fd, buffer, 1024);
    std::cout << "Received from server: " << buffer << std::endl;

    close(client_fd);
}

UDP サーバーとクライアント


// C++ UDP サーバープログラム
#include <iostream>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <unistd.h>

int main() {
    int server_fd = socket(AF_INET, SOCK_DGRAM, 0);
    sockaddr_in server_addr = {AF_INET, htons(12345), INADDR_ANY};

    bind(server_fd, (sockaddr*)&server_addr, sizeof(server_addr));
    std::cout << "UDP server is ready" << std::endl;

    char buffer[1024];
    sockaddr_in client_addr;
    socklen_t client_addr_len = sizeof(client_addr);

    while (true) {
        int len = recvfrom(server_fd, buffer, 1024, 0, (sockaddr*)&client_addr, &client_addr_len);
        std::cout << "Received message: " << buffer << std::endl;
        sendto(server_fd, "Hello from UDP server", 21, 0, (sockaddr*)&client_addr, client_addr_len);
    }

    close(server_fd);
}

// C++ UDP クライアントプログラム
#include <iostream>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <unistd.h>

int main() {
    int client_fd = socket(AF_INET, SOCK_DGRAM, 0);
    sockaddr_in server_addr = {AF_INET, htons(12345), inet_addr("127.0.0.1")};

    std::string message = "Hello from UDP client";
    sendto(client_fd, message.c_str(), message.length(), 0, (sockaddr*)&server_addr, sizeof(server_addr));

    char buffer[1024];
    socklen_t server_addr_len = sizeof(server_addr);
    recvfrom(client_fd, buffer, 1024, 0, (sockaddr*)&server_addr, &server_addr_len);
    std::cout << "Received from server: " << buffer << std::endl;

    close(client_fd);
}

Java: TCP と UDP サーバーとクライアント

TCP サーバーとクライアント


// Java TCP サーバープログラム
import java.io.*;
import java.net.*;

public class TcpServer {
    public static void main(String[] args) throws IOException {
        ServerSocket serverSocket = new ServerSocket(12345);
        System.out.println("Waiting for a TCP connection...");

        Socket clientSocket = serverSocket.accept();
        BufferedReader in = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));
        PrintWriter out = new PrintWriter(clientSocket.getOutputStream(), true);

        String data = in.readLine();
        System.out.println("Received data: " + data);

        out.println("Hello from TCP server");
        clientSocket.close();
        serverSocket.close();
    }
}

// Java TCP クライアントプログラム
import java.io.*;
import java.net.*;

public class TcpClient {
    public static void main(String[] args) throws IOException {
        Socket clientSocket = new Socket("127.0.0.1", 12345);
        PrintWriter out = new PrintWriter(clientSocket.getOutputStream(), true);
        BufferedReader in = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));

        out.println("Hello from TCP client");
        String response = in.readLine();
        System.out.println("Received from server: " + response);

        clientSocket.close();
    }
}

UDP サーバーとクライアント


// Java UDP サーバープログラム
import java.net.*;

public class UdpServer {
    public static void main(String[] args) throws Exception {
        DatagramSocket serverSocket = new DatagramSocket(12345);
        byte[] receiveData = new byte[1024];
        System.out.println("UDP server is ready");

        while (true) {
            DatagramPacket receivePacket = new DatagramPacket(receiveData, receiveData.length);
            serverSocket.receive(receivePacket);
            String message = new String(receivePacket.getData(), 0, receivePacket.getLength());
            System.out.println("Received message: " + message);

            String response = "Hello from UDP server";
            DatagramPacket sendPacket = new DatagramPacket(response.getBytes(), response.length(),
                    receivePacket.getAddress(), receivePacket.getPort());
            serverSocket.send(sendPacket);
        }
    }
}

// Java UDP クライアントプログラム
import java.net.*;

public class UdpClient {
    public static void main(String[] args) throws Exception {
        DatagramSocket clientSocket = new DatagramSocket();
        InetAddress serverAddress = InetAddress.getByName("localhost");

        String message = "Hello from UDP client";
        byte[] sendData = message.getBytes();
        DatagramPacket sendPacket = new DatagramPacket(sendData, sendData.length, serverAddress, 12345);
        clientSocket.send(sendPacket);

        byte[] receiveData = new byte[1024];
        DatagramPacket receivePacket = new DatagramPacket(receiveData, receiveData.length);
        clientSocket.receive(receivePacket);
        String response = new String(receivePacket.getData(), 0, receivePacket.getLength());
        System.out.println("Received from server: " + response);
        clientSocket.close();
    }
}

JavaScript : TCP と UDP サーバーとクライアント

TCP サーバーとクライアント


// Node.js TCP サーバープログラム
const net = require('net');
const server = net.createServer((socket) => {
    console.log('Client connected');

    socket.on('data', (data) => {
        console.log(`Received data: ${data}`);
        socket.write('Hello from TCP server');
    });

    socket.on('end', () => {
        console.log('Client disconnected');
    });
});

server.listen(12345, () => {
    console.log('Server is listening on port 12345');
});

// Node.js TCP クライアントプログラム
const net = require('net');
const client = net.createConnection({ port: 12345 }, () => {
    console.log('Connected to TCP server');
    client.write('Hello from TCP client');
});

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

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

UDP サーバーとクライアント


// Node.js UDP サーバープログラム
const dgram = require('dgram');
const server = dgram.createSocket('udp4');

server.on('message', (msg, rinfo) => {
    console.log(`Received message: ${msg} from ${rinfo.address}:${rinfo.port}`);
    server.send('Hello from UDP server', rinfo.port, rinfo.address);
});

server.bind(12345, () => {
    console.log('UDP server is ready');
});

// Node.js UDP クライアントプログラム
const dgram = require('dgram');
const client = dgram.createSocket('udp4');

client.send('Hello from UDP client', 12345, 'localhost', (err) => {
    if (err) console.error(err);
});

client.on('message', (msg) => {
    console.log(`Received from server: ${msg}`);
    client.close();
});

各言語の解説

言語メリットデメリット
Pythonシンプルで短いコード、動的な型付けで柔軟性が高い大規模システムでは速度が低下することがある
C#強力なライブラリとツールサポート、Windows環境に最適クロスプラットフォーム対応が限定されることがある
C++高速で低レベルな制御が可能メモリ管理などが難しい
Javaクロスプラットフォーム、広範なライブラリサポート初学者にはやや複雑でコードが冗長になることがある
JavaScript非同期処理が得意、フロントエンドとバックエンド両方に対応大規模プロジェクトでは管理が難しい場合がある

まとめ

この記事では、TCPとUDPのソケット通信の基礎を学び、Python、C#、C++、Java、JavaScript での実装例を紹介しました。次回は、ソケット通信を活用したより実践的なネットワークアプリケーションの開発方法について学びます。

よかったらシェアしてね!
  • URLをコピーしました!
  • URLをコピーしました!

コメント

コメントする

目次