0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Windows(受信)からUbuntsu(サーバ)へ接続しバイナリデータ受信

Last updated at Posted at 2025-05-25

目的

WindowsからUbuntsuへ接続しバイナリデータを受信する実験をしました。
2台をネットに繋がっていないポケットWIFIへ接続します。
ネットに繋げず完全に外界から隔絶された環境を作ります。
Ubuntsu側8080ポートで接続を受け付けます。
WindowsからIPアドレスを指定してUbuntuへ接続しバイナリデータを受信します。

実験風景

IMG_2006.jpeg
uploading...0

何度上げても失敗するのでこのままにしておいて後日あげます。

ネットの接続状態

使用したポケットWIFI

image.png

2台ともポケットWIFIへ接続

image.png
image.png

サーバ側UbuntuのIPアドレス


image.png

通信開始

Ubuntu接続受付

image.png

Windowsから接続

image.png

送信完了後Ubuntu

image.png

検証プログラム

client.c
/*
 * 【Windows受信クライアント】バイナリデータ受信プログラム
 * コンパイル: gcc client.c -o client.exe -lws2_32
 */

#include <stdio.h>
#include <stdlib.h>
#include <winsock2.h>
#include <stdint.h>

#pragma comment(lib, "ws2_32.lib")

/* 全データ受信関数 */
int recv_all(SOCKET sock, void *buffer, size_t length) {
    size_t total = 0;
    char *buf = (char*)buffer;
    while (total < length) {
        int received = recv(sock, buf + total, length - total, 0);
        if (received <= 0) return -1;
        total += received;
    }
    return 0;
}

int main() {
    WSADATA wsa;
    SOCKET sock;
    struct sockaddr_in server_addr;

    /* Winsock初期化 */
    if (WSAStartup(MAKEWORD(2, 2), &wsa) != 0) {
        printf("WSAStartup failed: %d\n", WSAGetLastError());
        return 1;
    }

    /* ソケット作成 */
    sock = socket(AF_INET, SOCK_STREAM, 0);
    if (sock == INVALID_SOCKET) {
        printf("Socket creation failed: %d\n", WSAGetLastError());
        WSACleanup();
        return 1;
    }

    /* サーバー設定(UbuntuのIPを指定) */
    memset(&server_addr, 0, sizeof(server_addr));
    server_addr.sin_family = AF_INET;
    server_addr.sin_port = htons(8080);
    server_addr.sin_addr.s_addr = inet_addr("192.168.0.101"); // UbuntuのIPに変更

    /* サーバー接続 */
    if (connect(sock, (struct sockaddr*)&server_addr, sizeof(server_addr)) == SOCKET_ERROR) {
        printf("Connection failed: %d\n", WSAGetLastError());
        closesocket(sock);
        WSACleanup();
        return 1;
    }

    printf("Connected to server\n");

    /* データサイズ受信 */
    uint32_t data_size;
    if (recv_all(sock, &data_size, sizeof(data_size)) < 0) {
        printf("Size reception failed\n");
        closesocket(sock);
        WSACleanup();
        return 1;
    }

    /* エンディアン変換 */
    data_size = ntohl(data_size);
    printf("Expected data size: %u bytes\n", data_size);

    /* データ受信 */
    char *buffer = malloc(data_size);
    if (!buffer) {
        printf("Memory allocation failed\n");
        closesocket(sock);
        WSACleanup();
        return 1;
    }

    if (recv_all(sock, buffer, data_size) < 0) {
        printf("Data reception failed\n");
        free(buffer);
        closesocket(sock);
        WSACleanup();
        return 1;
    }

    printf("Reception successful! Data content:\n");
    for (uint32_t i = 0; i < data_size; i++) {
        printf("%02X ", (unsigned char)buffer[i]);
    }
    printf("\n");

    /* 後処理 */
    free(buffer);
    closesocket(sock);
    WSACleanup();
    return 0;
}
server.c
/*
 * 【Ubuntu送信サーバー】バイナリデータ送信プログラム
 * コンパイル: gcc server.c -o server
 * 実行: ./server
 */

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <arpa/inet.h>
#include <sys/socket.h>

/* 全データ送信関数 */
int send_all(int sock, const void *buffer, size_t length) {
    size_t total = 0;
    const char *buf = (const char*)buffer;
    while (total < length) {
        ssize_t sent = send(sock, buf + total, length - total, 0);
        if (sent <= 0) return -1;
        total += sent;
    }
    return 0;
}

int main() {
    int server_sock, client_sock;
    struct sockaddr_in server_addr, client_addr;
    socklen_t addr_len = sizeof(client_addr);

    /* ソケット作成 */
    server_sock = socket(AF_INET, SOCK_STREAM, 0);
    if (server_sock < 0) {
        perror("ソケット作成失敗");
        exit(EXIT_FAILURE);
    }

    /* サーバー設定 */
    memset(&server_addr, 0, sizeof(server_addr));
    server_addr.sin_family = AF_INET;
    server_addr.sin_port = htons(8080);
    server_addr.sin_addr.s_addr = INADDR_ANY;

    /* バインド */
    if (bind(server_sock, (struct sockaddr*)&server_addr, sizeof(server_addr)) < 0) {
        perror("バインド失敗");
        close(server_sock);
        exit(EXIT_FAILURE);
    }

    /* 接続待機 */
    if (listen(server_sock, 1) < 0) {
        perror("待機失敗");
        close(server_sock);
        exit(EXIT_FAILURE);
    }

    printf("8080ポートで待機中...\n");

    /* クライアント接続受付 */
    client_sock = accept(server_sock, (struct sockaddr*)&client_addr, &addr_len);
    if (client_sock < 0) {
        perror("接続受付失敗");
        close(server_sock);
        exit(EXIT_FAILURE);
    }

    printf("クライアント接続: %s:%d\n", 
           inet_ntoa(client_addr.sin_addr), ntohs(client_addr.sin_port));

    /* 送信データ準備 */
    const char data[] = {0x48, 0x65, 0x6C, 0x6C, 0x6F, 0x21}; // "Hello!"
    uint32_t data_size = sizeof(data);
    uint32_t net_size = htonl(data_size);

    /* データサイズ送信 */
    if (send_all(client_sock, &net_size, sizeof(net_size)) < 0) {
        perror("サイズ送信失敗");
        close(client_sock);
        close(server_sock);
        exit(EXIT_FAILURE);
    }

    /* バイナリデータ送信 */
    if (send_all(client_sock, data, data_size) < 0) {
        perror("データ送信失敗");
        close(client_sock);
        close(server_sock);
        exit(EXIT_FAILURE);
    }

    printf("%d バイト送信成功\n", data_size);

    /* 後処理 */
    close(client_sock);
    close(server_sock);
    return 0;
}
0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?