広告
TCPを使ってWindowsとLinux間で通信してみる。
具体的にはWindows上にVirtualboxで仮想マシンを作成しHost-Only-Adapter経由で通信する。
構成
- サーバ : Linux CentOS 6, X86_64(64bit) on Virtualbox
- クライアント : Windows7 (32bit)
プログラム作成
クライアント側
実行バイナリはVisual Studio 2017 で作成。
TCP_Client.cpp
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 |
#include "stdafx.h" #include <stdio.h> #include <winsock2.h> #define PORT_NO_SERVER (12345) #define IP_ADDRESS_SERVER "192.168.100.254" int main(void) { WSADATA wsaData; struct sockaddr_in server; SOCKET sfd = -1; char buf[32] = { 0 }; int rc = 0; WSAStartup(MAKEWORD(2, 0), &wsaData); sfd = socket(AF_INET, SOCK_STREAM, 0); server.sin_family = AF_INET; server.sin_port = htons(PORT_NO_SERVER); server.sin_addr.S_un.S_addr = inet_addr(IP_ADDRESS_SERVER); rc = connect(sfd, (struct sockaddr *)&server, sizeof(server)); if (rc < 0) { printf("connect() failed(%d)\n", rc); exit(EXIT_FAILURE); } while (1) { memset(buf, 0, sizeof(buf)); int rs = recv(sfd, buf, sizeof(buf), 0); printf("recv %d byte, %s\n", rs, buf); } WSACleanup(); return 0; } |
プロジェクトプロパティから入力にws2_32.libを追記してビルドする。
Windows側のIPアドレスを 192.168.100.0/24のネットワークに設定しておく。
1 2 3 4 5 6 7 8 9 10 |
C:> ipconfig Windows IP 構成 イーサネット アダプター VirtualBox Host-Only Network: 接続固有の DNS サフィックス . . . : IPv4 アドレス . . . . . . . . . . : 192.168.100.1 サブネット マスク . . . . . . . . : 255.255.255.0 デフォルト ゲートウェイ . . . . . : |
サーバ側
tcp_server.c
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 |
#include <stdio.h> #include <stdlib.h> #include <string.h> #include <unistd.h> #include <sys/types.h> #include <sys/socket.h> #include <netinet/in.h> #include <errno.h> #define MAX_CLIENTS (1) #define MSGBUF_SIZE (1024) int main(void) { int sfd = -1; struct sockaddr_in client; int socklen = sizeof(client); int ac_sfd = -1; int rc = 0; struct sockaddr_in addr = { .sin_family = AF_INET, .sin_port = htons(12345), .sin_addr = { .s_addr = INADDR_ANY, }, }; /* ソケットの作成 */ sfd = socket(AF_INET, SOCK_STREAM, 0); if (sfd < 0) { perror("socket"); goto error_end; } rc = bind(sfd, (struct sockaddr *)&addr, sizeof(addr)); if (rc < 0) { perror("bind"); goto close_sfd_end; } rc = listen(sfd, MAX_CLIENTS); if (rc < 0) { perror("listen"); goto close_sfd_end; } /* 要求受付 */ ac_sfd = accept(sfd, (struct sockaddr *)&client, &socklen); if (ac_sfd < 0) { perror("accept"); goto close_sfd_end; } while (1) { /* メッセージ送信 */ char msgbuf[MSGBUF_SIZE] = "HELLO WORLD!"; ssize_t ws = write(ac_sfd, msgbuf, strlen(msgbuf)); if (ws < 0) { perror("write"); goto close_all_end; } sleep(1); } close_all_end: close(ac_sfd); close_sfd_end: close(sfd); error_end: return 0; } |
ソースコードのビルド
1 2 |
$ gcc tcp_server.c -o tcp_server $ |
こちらも通信インタフェースに同様のネットワークのIPアドレスを設定しておく。
1 2 3 4 5 |
$ ip -a addr 3: enp0s8: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP qlen 1000 link/ether 08:00:27:8c:e9:83 brd ff:ff:ff:ff:ff:ff inet 192.168.100.254/24 brd 192.168.100.255 scope global enp0s8 valid_lft forever preferred_lft forever |
実行結果
確かにサーバが送信した文字列をクライアントで受け取れている。
キャプチャを見ても確かに3WAYハンドシェイクからデータ送信まで行っている。
(ただし、クライアント→サーバのキャプチャは見えてない。理由不明。)
広告
広告