ソケット通信は、ネットワークプログラミングの基本であり、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 での実装例を紹介しました。次回は、ソケット通信を活用したより実践的なネットワークアプリケーションの開発方法について学びます。
コメント