• 締切済み

ソケットプログラミング

こんにちは。 ソケットプログラミングを勉強していて、音声を送りあえるIP電話らしきものを作ろうとしています。音声のやりとりは何とかできていますが、同時に文字列も送れるようにしたいです。ソケットをもう一つ作ればいいのではないかと思っていますが、実際に書いてみると、recv()の部分がうまく書けません。 音声データの送受信の部分は: while(1){ n=recv(sock,data1,N,0); //受信 if (n== -1){perror("recv");exit(1);} if(write(dsp, data1,n)==-1){perror("write"); exit(1);} //スピーカーから出力 n=read(dsp,data,N);  //マイクから入力 if (n== -1){perror("read");exit(1);} if(send(sock,data,n,0)==-1){perror("send");exit(1});} //送信 } 送信の時は n=read(0,tdata_2,N); send(sock_2,data_2,n,0); のように標準入力から文字列を読み込んで、data_2に格納し、新しく作ったソケットsock_2で送ればいいのですが、受信の時はどうしたらいいでしょうか。recv()をつかって、文字列と音声のデータを違うソケットで受け取って、違う配列に格納する方法があるでしょうか。 つまり、このような感じ(?): n1=recv(sock1,data1,N,0); //音声 n2=recv(sock2,data2,N,0); //文字列 とても悩んでますので、よろしくお願いします!!

みんなの回答

  • hidebun
  • ベストアンサー率50% (92/181)
回答No.1
roena88217
質問者

お礼

ありがとうございます!こういう関数があったんですね。助かりました。

関連するQ&A

  • ソケットプログラミングについて

    こんにちは。 以前、この掲示板に質問させていただいた者です。 送信側から受信側へWinsockを利用し、jpeg,mpegファイルを送信したいのですが、プログラムを実行すると強制終了されてしまいます。以下に主要部分を記述します。 [送信側] FILE *fp; char fname[100]; printf("読み込み用ファイルを入力して下さい:"); scanf("%s",fname); if((fp = fopen(fname,"rb")) == NULL){ printf("入力ファイルをオープンできない。\n"); exit(1); } char send_buf[1025]; int nRet; int n; while(n = fread(send_buf,1,1024,fp) != -1){ sendto(theSocket,send_buf,n,0,(LPSOCKADDR)&saServer,sizeof(struct sockaddr)); } fclose(fp); closesocket(theSocket); [受信側] FILE *fp; char fname[100]; printf("書き込み用ファイルを入力して下さい:"); scanf("%s",fname); if((fp = fopen(fname,"wb")) == NULL){ printf("出力ファイルをオープンできない。\n"); exit(1); } char Recv_buf[1025]; char size; SOCKADDR_IN saClient; while(1){ size = recvfrom(theSocket,Recv_buf,1024,0,(LPSOCKADDR)&saClient,&nLen); fwrite(Recv_buf,size,1,fp); } fclose(fp); closesocket(theSocket); 受信側を先に起動し、送信側を起動。送信側で1024バイトずつ送信し、受信側でwhileの無限ループを用いて送信側からのデータを受信するプログラムにしたつもりです。しかし、送信側で読み込みファイルを指定すると強制終了されてしまいます。ファイルオープンの仕方がおかしいのでしょうか?また、上記のプログラムでは1024バイトずつ送信できるようになっていますでしょうか? よろしくお願いします。

  • ソケットプログラミングによるファイル送信について

    VC++.NETを利用して、Winsockにてファイル送信プログラムを作成しています。ソケットはUDPを使用しています。 [行いたいこと] A→B端末へ、1024Byteずつバイナリデータ(画像)を送信。 [現在行っていること(A端末側のプログラムの概略)] 1.ファイルオープン 2.fread関数にてバイナリデータの入力(whileにてループ) 3.A→Bへパケットを1024Byteずつ送信。 #define DATA_SIZE 1024 main{ int n; char send_Buf[DATA_SIZE + 1]; if((fp = fopen(fname,"rb+")) == NULL){ printf("ファイルエラー\n"); exit(1); } //nが0でなくなったら、ループを抜ける。 while((n = fread(send_Buf,1,DATA_SIZE,fp)) != 0) { sendto(s, send_Buf, n, 0, (LPSOCKADDR)&addrin, sizeof(addrin)); } } A側でビルドはできますがエラーが発生して実行できません。 よろしければ教えていただけないでしょうか。C言語の基礎もきちんと出来ていないからなのかもしれません・・・>< よろしくお願いします。

  • ソケットプログラミングに関する質問です

    ソケットプログラミングに関する質問です 最近ソケットプログラムに興味があり、勉強をしているのですが、 手始めにと下記の2つのプログラムをそのまま記述し http://cs.baylor.edu/~donahoo/practical/CSockets/code/TCPEchoClient.c http://cs.baylor.edu/~donahoo/practical/CSockets/code/TCPEchoServer.c TCPEchoClientプログラムから送信した英数字をTCPEchoServerがキャッチして TCPEchoClientの方へ送り返すプログラムを作ってみました。 その後、応用として手始めにTCPEchoClient側の送信元IPアドレスと送信した文字列 ex: 192.xxx.xxx.xx 'Hello World!' を送り返すプログラムを作成するために、 同じサイト内にあったHandleTCPClientを下記の通り 改造してみたのですが、引数に問題があるとエラーが出て先へ進めません。>< #include<stdio.h> #include<sys/socket.h> #include<unistd.h> #define RCVBUFSIZE 256 /* 受信バッファのサイズ */ void DieWithError(char *errorMessage); /* エラー処理関数 */ void HandleTCPClient(int clntSocket, int echoClntAddr) /* TCPクライアント関数処理 */ { char echoBuffer[RCVBUFSIZE]; /* エコー文字列のバッファ */ int recvMsgSize; /* 受信メッセージのサイズ */ struct clintIP echoClntAddr; /* クライアントのIPを取得 */ /* クライアントからの受信メッセージ */ if ((recvMsgSize = recv(clntSocket, echoBuffer, RCVBUFSIZE,clintIP,0)) < 0) DieWithError("recv() failed"); /* 受信した文字列を送信し、転送が終了していなければ次を受信する */ while (recvMsgSize > 0) /* 0は転送の終了を意味する */ { /* メッセージをクライアントにエコーバックする */ if (send(clntSocket,echoBuffer,recvMsgSize, 0) != recvMsgSize) DieWithError("send() failed"); /* 受信するデータが残っていないか確認する。 */ if ((recvMsgSize = recv(clntSocket, echoBuffer,RCVBUFSIZE, 0)) < 0) DieWithError("recv() failed"); } close(clntSocket); /* クライアントソケットをクローズする */ } 単純にTCPEchoServerの echoClntAddr.sin_addrという箇所が送信元のIPを 引っ張ってきてるからHandleTCPClientの方へ 関数をstructで引っ張ってくればいいと思ったのですが、そういうわけでもないのです。

  • C言語でのネットワークプログラミング

    現在Linuxを用いてC言語でTCP/IPのサーバ、クライアントプログラムを作成しています。 sendとrecvの正しい使い方がわかっておりません。 一度のrecvですべてのデータを受け取れないことはわかっているのですが、どのように記述するのが良いのでしょうか。1バイトずつrecvするのは大間違いであると何処かのサイトで読みました。 ・現在の仕様 サーバがデータの文字列をsendで送ってくる クライアントはrecvで1バイト読み込みを繰り返し、配列に格納し、\0を見つけるとループを抜ける recvした文字列を画面表示 表示したあとはrecvに戻る

  • 前回はごめんなさい。pythonでcgiとソケット

    どうもこんにちは。 この前の質問は補足しようと思いサブアカウントを作成したら 利用規約に引っかかったみたいで削除されてしまいました。 自分が何も知らないばかりに回答者の方々には不快な思いをさせてしまったことをお詫びします。 本題ですが、 pythonのプログラムをサーバーで動かそうと思って、 .cgiのファイルを作成しました。 そして、httpの形にして文字を表示することは出来たのですが、 本当にしたいのはソケット通信なんです。 自分のPCでのソケット通信(サーバー&クライアント)はできますし、 cgiも簡単なものなら動くようになりました。 が、cgiでソケット通信ができません。 httpのリクエストでgetしろよ。と思うかもしれませんが、 ソケット通信じゃないとダメなんです。 無理なら諦めますが、出来るならやり方を教えて下さい。 自分のPCでのソケット通信のプログラムは以下のものとなります。 #!/usr/local/bin/python #coding: utf-8 import socket import time host = "localhost" port = 50000 data = "HOST:"+host+"\nPort:"+str(port) port = int(port) print ("python socket server") print (data) while(True): print ("wait...\n") sock_server = socket.socket(socket.AF_INET, socket.SOCK_STREAM) sock_server.bind((host, port)) sock_server.listen(1) connect, addr = sock_server.accept() print ("Connect...\naddress:", addr) while(True): mes = connect.recv(1024) if not mes : break print ("Getmessage:", mes) connect.send("server message") print ("send message:server message") sock_server.close() これをサーバーに移そうと思うとこのままですとlocalhostでエラーが出ます。 なのでこれをgethostnameやgethostbynameにしようとすると、 こりゃまたエラーが出てしまいます。 どうしたら出来るのでしょうか?? サーバーは@pagesを今は使っていますが、 将来的には個人のサーバー(独自ドメインの)で動かすことになると思います。

    • ベストアンサー
    • CGI
  • WinSockを用いたUDP送受信ソケットプログラミングについて

    こんにちは。 現在、VC++.NETでWinSockを用いたUDPソケットプログラミングを行っています。以下のようなプログラムを作りたいと思っているのですがうまく動作しません。 [概要] A:送信端末 B:受信端末 1.Aから文字列"send"をB端末へ送信。 2."send"を受信した受信端末Bは、A端末へ文字列"ok"を送信。 この1と2の動作を行わせたいと思っています。この場合、A,B端末は送信と受信を行う必要があります。 [問題点(うまくいかない点)] A→Bへ"send"は送信でき、B端末で受信できるのですが、B端末からA端末へ送信できません。B端末で送信できているのか、それともA端末で受信できていないのか?が分からない状態です。 [気づいた点] ポート番号を分ける必要があるのでしょうか?例えば、A→Bへは9000番。B→Aへは9001番という意味です。 送信と受信を行うため、送信・受信で2つのUDPソケットを使用する必要があるのでしょうか?例えば、 s1 = socket(AF_INET, SOCK_DGRAM, 0);←送信に利用 s2 = socket(AF_INET, SOCK_DGRAM, 0);←受信に利用 よろしくお願いします。

  • if文の中ではwinsockのsendが出来ない?

    struct C_Commu { ----WSADATA wsadata; ----SOCKET Sock; ----sockaddr_in Addr; public: ----void Init(); ----void Send(); } というクラスがあったとします。 Init()ではソケットの生成だとかWinsockを使った通信で必要な設定を行っています。(TCPとする) void C_Commu::Send() { ----send( Sock, "hello", 5, 0 ); ----if(何らかの条件) ----{ --------send( Sock, "hello", 5, 0 ); ----} } このような関数の場合に、if文の外のsend()をコメントアウトしたりコメントにしたりして動作を確認してみたところ if文の外のsend()にはサーバーが反応するのですが、if文内のsend()はsend()が行われているのが確認されるのにもかかわらずサーバー側が一切反応しません。 ここでいう、サーバーが反応するとは、select()を用いてブロッキングが解除されてrecv()に処理が回れば反応した、recv()に処理が行かなければ反応していない、としています。 これはどうしてでしょうか?

  • Linux C言語 ソケット通信について

    C言語でソケット通信のプログラムを始めて作成しました。 受信時のデータ量が少ない場合は問題ないのですが、データ量が多くなると、 サーバーの受信が、出来たり、出来なかったりと不安定になります。 ログを確認しますと、パケットが勝手に分割されサーバーで受信した場合に、 おかしな動きになることがわかりました。 なぜそのようになるのか、また何がいけないのかわかりません。 どうぞご教授をお願いします。 FD_ZERO(&r_socket); FD_SET(sock, &r_socket); width = sock+1; *leng = 0; ef = TRUE; memset(&s,0x00,sizeof(s)); /* タイムアウト設定 */ time.tv_sec = 3; time.tv_usec = 0; while(1) { /* 受信待機 */ ret = select(width, &r_socket, NULL, NULL, &time) if ( ret < 0 ) { "受信待機エラー"表示 break; } if ( ret = 0 ) { "タイムアウトエラー"表示 break; } /* パケットを受信 */ if ( FD_ISSET(sock, &r_socket)) { memset(&rb,0x00,sizeof(rb)); read_len = read(sock, rb, sizeof(rb)); "受信した内容をログに出力" /* 割り込み中断エラーは継続し、その他エラーは終了する */ if ( read_len < 0 ) { if ( errno == EINTR ) { continue; } else { ef = FALSE; "受信エラー"表示 break; } } /* クライアントのソケットが閉じた場合は終了する */ if ( read_len == 0 ) { break; } /* データ送信要求を受信した場合は終了する */ if ( rb[read_len-1] == ACK ) { break; } /* 受信バッファーへ取り込み */ if ( rb[read_len-1] == ETX || rb[read_len-1] == ETB ) { len = read_len - 1; } else { len = read_len; } for (i = 0;i < len;i++) { if ( rb[i] != ETB ) { rsbuf[(*leng)++] = rb[i]; } } /* 最終データ時は終了する */ if ( rb[read_len-1] == ETX ) { break; } /* 最終データでない場合はデータ送信要求を送信する */ if ( rb[read_len-1] == ETB ) { sprintf(trxmsg,"%1c",ACK); ef = send_socket(sock, strlen(trxmsg), trxmsg); if ( ef != TRUE ) { break; } } } }

  • TCP/IP通信型大文字・小文字変換プログラム

    TCP/IP通信型大文字・小文字変換プログラムを作りたいです。 しかし、うまく2つのプログラムが接続されません。 恐らく、IPアドレスやホスト名の問題だと思います。 超初心者でそこのところをあまり理解していません。 どなたかプログラムの補足をお願いします。 概要は ・クライアント キーボードから文字列を入力し、サーバーに送信。 サーバーから送信された文字列を画面に出力。 ・サーバー クライアントから送信された文字列に対し、 大文字は小文字に、小文字は大文字に変換して返す。 クライアント側プログラム #include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <sys/socket.h> #include <arpa/inet.h> #include <netinet/in.h> #define SOCK_NAME "./socket" int main() { struct sockaddr_in saddr; int soc; char buf[1024]; if ( (soc =socket(AF_INET, SOCK_STREAM, 0 ) ) < 0 ) { perror("socket"); exit(1); } memset((char *)&saddr, 0, sizeof(saddr)); saddr.sin_family = AF_INET; saddr.sin_addr.s_addr=inet_addr("192.168.1.1"); saddr.sin_port=htons(1357); if(connect(soc, (struct sockaddr *)&saddr, sizeof(saddr)) < 0) { perror("connect"); exit(1); } fprintf(stderr, "Connection established: socket %d used.\n", soc); while(fgets(buf, 1024, stdin)){ if(buf[strlen(buf) -1] == "\n") buf[strlen(buf) -1] = "\0"; write(soc, buf, 1024); read(soc, buf, 1024); fprintf(stdout, "%s\n", buf); } close(soc); return 0; } サーバー側プログラム #include <stdio.h> #include <stdlib.h> #include <ctype.h> #include <unistd.h> #include <sys/socket.h> #include <arpa/inet.h> #define SOCK_NAME "./socket" int main() { int i; int fd1, fd2; struct sockaddr_in saddr; struct sockaddr_in caddr; int len; int ret; char buf[1024]; if((fd1 =socket(AF_INET, SOCK_STREAM, 0)) < 0 ){ perror("socket"); exit(1); } memset((char *)&saddr, 0, sizeof(saddr)); saddr.sin_family = AF_INET; saddr.sin_addr.s_addr=INADDR_ANY; saddr.sin_port=htons(1357); unlink(SOCK_NAME); if(bind(fd1, (struct sockaddr *)&saddr, sizeof(saddr)) < 0) { perror("bind"); exit(1); } if(listen(fd1,5) < 0 ) { perror("listen"); exit(1); } while(1){ len = sizeof(caddr); if((fd2 = accept(fd1, (struct sockaddr *)&caddr, &len)) < 0){ perror("accept"); exit(1); } fprintf(stderr, "Connection established: socket %d used.\n", fd2); while((ret = read(fd2, buf, 1024)) > 0 ){ fprintf(stderr, "read: &s\n", buf); for(i=0; i<ret; i++) if(islower(buf[i])) buf[i] = toupper(buf[i]); if(isupper(buf[i])) buf[i] = tolower(buf[i]); fprintf(stderr, "write: %s\n", buf); write(fd2, buf, 1024); } close(fd2); } close(fd1); return 0; }

  • winsock recvでの文字化け

    Winsockによりサーバ名、ポート番号、URLを指定するとそのソースファイルをテキスト出力するプログラミングを作成しています。 文字エンコーディングがShift_JISであるページは日本語も正しく表示させることができたのですが、それ以外の文字エンコーディング(EUC-JP、Unicode(UTF-8))のページでは日本語が文字化けしてしまいうまく出力できません。 デバックでrecv関数で文字を取得した際の変数szStrRcvを確認したところ、取得した時点で既に文字化けしているようです。 以下に問題部のソースを示します。 開発環境:WindowsXP Visualstudio.NET2003 VisualC++ WSADATA wsaData; LPHOSTENT lpHost; SOCKET s; int nRtn; SOCKADDR_IN sockadd; _TCHAR szStrRcv[1024]; char szURL[1024] //URL char szStr[256], szYN[4]; u_short sock_port; unsigned int addr; fp = fopen(filename, "a"); sock_port = (u_short)atoi(port); s = socket(PF_INET, SOCK_STREAM, 0); if (s == INVALID_SOCKET) { //perror("ソケットをオープンできません\n"); //WSACleanup(); //return -2; } lpHost = gethostbyname(host); if (lpHost == NULL) { addr = inet_addr(host); lpHost = gethostbyaddr((char *)&addr, 4, AF_INET); //wsprintf(szStr, "%sが見つかりません\n", host); //perror(szStr); //WSACleanup(); //return -3; } memset(&sockadd, 0, sizeof(sockadd)); sockadd.sin_family = AF_INET; sockadd.sin_port = htons(sock_port); sockadd.sin_addr = *((LPIN_ADDR)*lpHost->h_addr_list); if (connect(s, (PSOCKADDR)&sockadd, sizeof(sockadd)) != 0) { //perror("サーバーソケットに接続失敗\n"); closesocket(s); } wsprintf(szStr, "GET %s\n", szURL); //szURLには正常にURLが入っている nRtn = send(s, szStr, (int)strlen(szStr), 0); while(1) { memset(szStrRcv, '\0', sizeof(szStrRcv)); ///////////////////////////問題の部分///////////////////////////// nRtn = recv(s, szStrRcv, (int)sizeof(szStrRcv) - 1, 0); _ftprintf(fp, _T("%s\n"), szStrRcv); //HTMLソースを.txtに書き込む //////////この時点でszStrRcvには日本語が文字化けした内容が格納されている/////////////// if (nRtn == 0) break; if (nRtn == SOCKET_ERROR) { perror("recvエラーです\n"); break; } } closesocket(s); WSACleanup(); fclose(fp); 何か対策がありましたらご教授をお願いいたします。

専門家に質問してみよう