//----------------------------------------------------------------- // tcp_lib.c: ソケット通信によるデータ転送用ライブラリ //----------------------------------------------------------------- #include "tcp_lib.h" //----------------------------------------------------------------- // IPアドレスの取得 //----------------------------------------------------------------- // ホスト名からIPアドレスの取得 char* GetIP(char* hostname) { struct in_addr ipv4; unsigned long haddr; struct hostent *phost = gethostbyname(hostname); haddr = *((unsigned long *)((phost->h_addr_list)[0])); ipv4.s_addr = haddr; return inet_ntoa(ipv4); } // ホスト名の表示 void Disp_ipinfo(char* msg,int portno) { char hostname[100]; gethostname(hostname,sizeof(hostname)); printf("** %s\n",msg); printf(" %s[%s]: %d\n",hostname,GetIP(hostname),portno); } //----------------------------------------------------------------- // // サーバ用 // //----------------------------------------------------------------- int TCP_accept(int acc,char* clhost) { struct in_addr ipv4; struct sockaddr_in from; int sockadrlen = sizeof(from); int ack = accept(acc,(struct sockaddr*)&from,&sockadrlen); ipv4 = from.sin_addr; sprintf(clhost,"%s",inet_ntoa(ipv4)); return ack; } int TCP_acc_port(int portno) { int s; struct sockaddr_in addr; if((s=socket(AF_INET,SOCK_STREAM,0)) < 0){ perror("socket"); return -1; } addr.sin_family = AF_INET; addr.sin_addr.s_addr = INADDR_ANY; addr.sin_port = htons(portno); if(bind(s,(struct sockaddr *)&addr,sizeof(addr)) < 0){ perror("bind"); fprintf(stderr,"port number %d is already used." "kill another program.",portno); return -1; } listen(s,5); return s; } //----------------------------------------------------------------- // // クライアント用 // //----------------------------------------------------------------- // ホスト-ポート先指定のソケット通信開始 int TCP_open(char* hostname,int portno) { int sock = TCP_connect(hostname,portno); if(sock<0) return -1; return sock; } int TCP_connect(char *hostname,int portno) { int s; struct hostent *hostent; struct sockaddr_in addr; addr.sin_family = AF_INET; if((hostent = gethostbyname(hostname)) == NULL) { fprintf(stderr,"unknown host %s\n",hostname); return -1; } bcopy(hostent->h_addr,(char*)&addr.sin_addr,hostent->h_length); addr.sin_port = htons(portno); if((s=socket(AF_INET,SOCK_STREAM,0)) < 0){ perror("socket"); return -1; } if(connect(s,(struct sockaddr *)&addr,sizeof(addr)) < 0){ perror(hostname); close(s); return -1; } return s; } // ソケット通信終了 void TCP_close(int sock) { close(sock); } //----------------------------------------------------------------- // ソケットをファイル記述子に割り当て //----------------------------------------------------------------- int fdopen_sock(int sock,FILE **inp,FILE **outp) { int sock2; if((sock2=dup(sock)) < 0) { perror("dup"); return -1; } if((*inp = fdopen(sock2,"r")) == NULL) { perror("fdopen:r"); close(sock2); return -1; } if((*outp = fdopen(sock,"w")) == NULL) { perror("fdopen:w"); fclose(*inp); *inp = 0; return -1; } // setvbuf() によりバッファリングなしの設定. // 出力内容を即座にネットワークに送信 setvbuf(*outp,(char *)NULL,_IOLBF,0); return 0; } //----------------------------------------------------------------- // // ソケットによる送受信 // //----------------------------------------------------------------- // 送信(See: UNIX Network Programming, SS.6.6, Utility routines) int TCP_send(int sock,BYTE* buff,int nbytes) { register int nleft, nwritten; nleft = nbytes; while(nleft > 0) { nwritten = write(sock,buff,nleft); if(nwritten <= 0) return nwritten; nleft -= nwritten; buff += nwritten; } return (nbytes - nleft); } //----------------------------------------------------------------- // 受信 //----------------------------------------------------------------- int TCP_recv(int sock,BYTE* recbuf,int timeout) { int rbyte; struct timeval tout; // タイムアウト時間 fd_set fds; memset(recbuf,0,sizeof(BYTE)*BUFSIZ); if(timeout){ tout.tv_sec = timeout;//TIMEOUT_SEC; tout.tv_usec = 0;//TIMEOUT_USEC; FD_ZERO(&fds); // fd_set 初期化 FD_SET(sock,&fds); // sock 設定 select(sock+1,&fds,NULL,NULL,&tout); // データ受信待ち if(FD_ISSET(sock,&fds)){ // 該当sock 読み込みデータあり rbyte = read(sock,recbuf,BUFSIZ); } if(rbyte < 0) rbyte = 0; } else { rbyte = read(sock,recbuf,BUFSIZ); if(rbyte < 0) rbyte = 0; } return rbyte; }