Skip to content

Instantly share code, notes, and snippets.

@tdkn
Created July 6, 2012 04:10
Show Gist options
  • Save tdkn/3058020 to your computer and use it in GitHub Desktop.
Save tdkn/3058020 to your computer and use it in GitHub Desktop.
secure kadai 20120706
// file-send.c
#include <stdio.h>
#include <string.h>
#include <sys/socket.h>
#include <netdb.h>
#include <fcntl.h>
int main(int argc, char *argv[]) {
char *port = "9876";
char buf[65536];
struct addrinfo hints;
struct addrinfo *res0;
struct addrinfo *res1;
int sock;
// ヒント情報の生成
memset(&hints, 0, sizeof(hints));
hints.ai_socktype = SOCK_STREAM;
hints.ai_family = PF_UNSPEC;
// サーバ名とポート名の解決を行い、addrinfo リスト(res0)を取得
int error = getaddrinfo(argv[1], port, &hints, &res0);
if(error) {
fprintf(stderr, "%s: %s\n", port, gai_strerror(error));
return 1;
}
// res0 から next を順にたどり成功するまで試行を続ける
for(res1 = res0; res1 != NULL; res1 = res1 -> ai_next) {
// ソケットの生成
sock = socket(res1->ai_family, res1->ai_socktype, res1->ai_protocol);
// ソケットの生成に失敗したらリストの次の項目を試す
if(sock < 0){
continue;
}
// ソケットが生成できたらサーバへ接続を試みる
if(connect(sock, res1->ai_addr, res1->ai_addrlen) != 0) {
close(sock);
continue;
}
// for ループを脱出
break;
}
// すべてのアドレスを含んだリストを開放
freeaddrinfo(res0);
// すべてのaddrinfoが失敗したら接続失敗
if(res1 == NULL) {
printf("failed\n");
return 1;
}
// サーバとのデータのI/O
int n, ret;
int fd = open(argv[2], O_RDONLY);
while((n = read(fd, buf, sizeof(buf))) > 0) {
ret = write(sock, buf, n);
if(ret < 1) {
perror("write");
break;
}
}
// TCPセッションの終了
close(sock);
return 0;
}
// file-server.c
#include <stdio.h>
#include <string.h>
#include <sys/socket.h>
#include <netdb.h> // addrinfo structure
#include <fcntl.h> // open();
int main(int argc, char *argv[]) {
char *port = "9876";
char buf[65536];
struct sockaddr_in client;
struct addrinfo hints;
struct addrinfo *res;
int sock0;
int sock1;
// init sockaddr_in structure
memset(&hints, 0, sizeof(hints));
hints.ai_family = AF_INET;
hints.ai_flags = AI_PASSIVE;
hints.ai_socktype = SOCK_STREAM;
int error = getaddrinfo(NULL, port, &hints, &res);
if(error != 0) {
printf("getaddrinfo : %s\n", gai_strerror(error));
return 1;
}
// create socket(sock0)
sock0 = socket(res->ai_family, res->ai_socktype, 0);
if(sock0 < 0) {
perror("socket");
return 1;
}
// socket address is intended for 'bind' (AI_PASSIVE)
if(bind(sock0, res->ai_addr, res->ai_addrlen) != 0) {
perror("bind");
return 1;
}
freeaddrinfo(res); // free addrinfo structure
// wait for TCP client connection
listen(sock0, 5);
// 接続要求が来たクライアントとの通信ソケットを返す
// プロトコル種別に応じたソケットアドレスを返す
int len = sizeof(client);
sock1 = accept(sock0, (struct sockaddr *)&client, &len);
if(sock1 < 0) {
perror("accept");
return 1;
}
// クライアントとのデータのI/O
int n, ret;
// O_WRONLY: 書きこみ専用モードで開く
// O_CREAT: 新規ファイルを作成し、書きこみモードで開く
int fd = open(argv[1], O_WRONLY | O_CREAT, S_IRUSR | S_IWUSR);
while((n = read(sock1, buf, sizeof(buf))) > 0) {
ret = write(fd, buf, n);
if(ret < 1) {
perror("write");
break;
}
}
close(sock1);
close(sock0);
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment