テキストを送り合う最小のプログラムを、サーバ側とクライアント側の両方で作る。
socket() — ソケットを作るbind() — ポートに紐付けlisten() — 待ち受け開始accept() — 接続を受け取るrecv() / send()close()socket() — ソケットを作るconnect() — サーバに接続send() / recv()close()bind/listen/accept がサーバ特有、connect がクライアント特有。それ以外は共通です。#include <stdio.h> #include <string.h> #include <unistd.h> #include <arpa/inet.h> #include <sys/socket.h> #define PORT 12345 #define BUF_SIZE 1024 int main(void) { // 1. ソケット作成 int listen_fd = socket(AF_INET, SOCK_STREAM, 0); if (listen_fd < 0) { perror("socket"); return 1; } // (推奨)アドレス再利用を許可 int yes = 1; setsockopt(listen_fd, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(yes)); // 2. 待ち受けアドレスを準備 struct sockaddr_in addr; memset(&addr, 0, sizeof(addr)); addr.sin_family = AF_INET; addr.sin_addr.s_addr = htonl(INADDR_ANY); // すべてのIPで待ち受け addr.sin_port = htons(PORT); // 3. bind — ポートを紐付け if (bind(listen_fd, (struct sockaddr*)&addr, sizeof(addr)) < 0) { perror("bind"); return 1; } // 4. listen — 待ち受け開始 if (listen(listen_fd, 1) < 0) { perror("listen"); return 1; } printf("ポート %d で待ち受け中...\n", PORT); // 5. accept — 1クライアントを受け入れ struct sockaddr_in client_addr; socklen_t clen = sizeof(client_addr); int conn_fd = accept(listen_fd, (struct sockaddr*)&client_addr, &clen); if (conn_fd < 0) { perror("accept"); return 1; } printf("クライアント接続: %s\n", inet_ntoa(client_addr.sin_addr)); // 6. 受信してそのまま返す(エコー) char buf[BUF_SIZE]; ssize_t n; while ((n = recv(conn_fd, buf, BUF_SIZE - 1, 0)) > 0) { buf[n] = '\0'; printf("受信: %s", buf); send(conn_fd, buf, n, 0); // そのまま送り返す } // 7. 後片付け close(conn_fd); close(listen_fd); printf("接続を閉じました\n"); return 0; }
inet_addr("127.0.0.1") などを指定します。#include <stdio.h> #include <string.h> #include <unistd.h> #include <arpa/inet.h> #include <sys/socket.h> #define PORT 12345 #define BUF_SIZE 1024 int main(void) { // 1. ソケット作成 int sockfd = socket(AF_INET, SOCK_STREAM, 0); if (sockfd < 0) { perror("socket"); return 1; } // 2. 接続先(localhost:12345)を設定 struct sockaddr_in addr; memset(&addr, 0, sizeof(addr)); addr.sin_family = AF_INET; addr.sin_port = htons(PORT); addr.sin_addr.s_addr = inet_addr("127.0.0.1"); // 3. connect — サーバに接続 if (connect(sockfd, (struct sockaddr*)&addr, sizeof(addr)) < 0) { perror("connect"); return 1; } printf("サーバに接続しました。メッセージを入力してEnter:\n"); // 4. 標準入力から1行読み取って送信 char msg[BUF_SIZE]; if (fgets(msg, BUF_SIZE, stdin) == NULL) return 1; send(sockfd, msg, strlen(msg), 0); // 5. 返ってきた文字列を受信 char buf[BUF_SIZE]; ssize_t n = recv(sockfd, buf, BUF_SIZE - 1, 0); if (n > 0) { buf[n] = '\0'; printf("サーバからの返答: %s", buf); } // 6. 切断 close(sockfd); return 0; }
127.0.0.1(localhost)に接続しているので、同じPC上でサーバを動かしておく必要があります。別のマシンに接続する場合はそのマシンのIPアドレスに変えてください。bind: Address already in use — ポートが他のプロセスで使用中。少し待って再試行、またはポート番号を変更。connect: Connection refused — サーバが起動していないか、ポート番号/IPが違う。toupper(<ctype.h>)を使う。accept の後に fork() で子プロセスを作り、複数クライアントを同時に相手できるようにせよ。親プロセスは accept ループに戻る。