今回提出期限は明日なのですが、未だにほとんどできていないため書き込ませていただきます。
複数とチャットを行うプログラムを作成しております。
ルール
・サーバを作らずP2P通信で行うこと
・時報を流す(これのみサーバ可)
・ブラックリストを作り、その人にデータを送らないようにする
問題点
・送受信できていない。
サーバとクライアントという関係ではないので作り方がわからない
・ブラックリストの作り方の発想が全く分からない。
全く浮かばず・・・ポート番号でしょうか?
またコードを記載させていただきます、どうかよろしくお願いいたします。
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <stdio.h>
#include <unistd.h>
#include <sys/wait.h>
#include <stdlib.h>
#include <time.h>
#include <string.h>
#include <arpa/inet.h>
#include <pthread.h>
int sd;
int port;
int acc_sd;
//構造体の宣言
struct sockaddr_in addr;
char message[256], *p;
//アドレスの長さを格納
socklen_t sin_size;
struct sockaddr_in from_addr;
//受信バッファ
char buf[2048];
//スレッド
pthread_t th1, th2, th3, th4;
//受信スレッド
void *recv_thread(void *arg)
{
//printf("exitが入力された場合、終了します\n");
// IPv4 TCP のソケットを作成する
if((sd = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
perror("socket");
//return -1;
}
// 送信先アドレスとポート番号を設定する
addr.sin_family = AF_INET;
addr.sin_port = htons(port);
addr.sin_addr.s_addr = inet_addr("127.0.0.1");
// バインドする
if(bind(sd, (struct sockaddr *)&addr, sizeof(addr)) < 0) {
perror("bind");
return 0;
}
// パケット受信待ち状態とする
// 待ちうけキューを10としている
if(listen(sd, 10) < 0) {
perror("listen");
return 0;
}
// クライアントからコネクト要求が来るまで停止する
// 以降、サーバ側は acc_sd を使ってパケットの送受信を行う
if((acc_sd = accept(sd, (struct sockaddr *)&from_addr, &sin_size)) < 0) {
perror("accept");
return 0;
}
while (1) {
// 受信バッファの初期化
memset(buf, 0, sizeof(buf));
// パケット受信。パケットが到着するまでブロック
if(recv(acc_sd, buf, sizeof(buf), 0) < 0) {
perror("recv");
return 0;
}
// 受信データの出力
printf(">>message ");
printf("%s", buf);
printf("\n");
FILE *fp; //ファイルポインター
fp = fopen("test3.txt","a"); //ファイルを開く
time_t now = time(NULL);
struct tm *pnow = localtime(&now);
char buff[128]="";
sprintf(buff,"%d:%d:%d",pnow->tm_hour,pnow->tm_min,pnow->tm_sec);
char *addrstr = inet_ntoa(from_addr.sin_addr);
//ファイルに書きこむ
fprintf(fp,"message:%s",buf); //区切り文字:スペース
fprintf(fp," , time:%s",buff);
fprintf(fp," , address:%s",addrstr);
fprintf(fp,"\n");
fclose(fp); //ファイルを閉じる
if (!strncmp(buf, "exit", 4)) break;
}
return NULL;
}
//送信スレッド
void *send_thread(void *arg)
{
// IPv4 TCP のソケットを作成する
if((sd = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
perror("socket");
return 0;
}
// 送信先アドレスとポート番号を設定する
addr.sin_family = AF_INET;
addr.sin_port = htons(port);
addr.sin_addr.s_addr = inet_addr("127.0.0.1");
while (1) {
printf(">>message:");
fgets(message, sizeof(message), stdin);
if ((p = strchr(message, '\n'))) *p = 0;
// サーバ接続(TCP の場合は、接続を確立する必要がある)
connect(sd, (struct sockaddr *)&addr, sizeof(struct sockaddr_in));
// パケットを TCP で送信
if(send(sd, message, 256, 0) < 0) {
perror("send");
return -1;
}
FILE *fp; //ファイルポインター
fp = fopen("test3.txt","a"); //ファイルを開く
time_t now = time(NULL);
struct tm *pnow = localtime(&now);
char buff[128]="";
sprintf(buff,"%d:%d:%d",pnow->tm_hour,pnow->tm_min,pnow->tm_sec);
unsigned long long_addr = 2085852108ul;
struct in_addr inaddr = { htonl(long_addr) };
char *addrstr = inet_ntoa(inaddr);
//ファイルに書きこむ
fprintf(fp,"message:%s",message); //区切り文字:スペース
fprintf(fp," , time:%s",buff);
fprintf(fp," , address:%s",addrstr);
fprintf(fp,"\n");
fclose(fp); //ファイルを閉じる
int fclose(FILE *fp);
if (!strncmp(message, "exit", 4)) break;
}
return NULL;
}
//時報スレッド
void *cm_thread(void *arg)
{
int i;
while(1){
// 5秒待ち
for (i = 0; i < 5; i++) {
// 1秒毎に終了チェック
sleep(1);
}
printf("広告情報受け取る(仮)\n");
}
return NULL;
}
//ブラックリストスレッド
void *black_thread(void *arg)
{
while(message == 0){
printf("ブラックリストを作ります\n");
}
return NULL;
}
int main(int argc, char** argv)
{
//スレッド生成
pthread_create(&th1, NULL, recv_thread, sd);
pthread_create(&th2, NULL, send_thread, sd);
pthread_create(&th3, NULL, cm_thread, sd);
pthread_create(&th4, NULL, black_thread, sd);
//終了処理
while (fgets(message, sizeof message, stdin) && strncmp(message, "exit", 4)
printf("終了する場合はexitを入力してください\n");
//ソケットのクローズ
close(sd);
//スレッド削除
pthread_join(th1, NULL);
pthread_join(th2, NULL);
pthread_join(th3, NULL);
pthread_join(th4, NULL);
return 0;
}