ソケットプログラミングのマルチプロセス・マルチタスクについて。

フォーラム(掲示板)ルール
フォーラム(掲示板)ルールはこちら  ※コードを貼り付ける場合は [code][/code] で囲って下さい。詳しくはこちら
ツンドラ

ソケットプログラミングのマルチプロセス・マルチタスクについて。

#1

投稿記事 by ツンドラ » 12年前

ソケットプログラミング初心者です。UNIX環境C言語で学んでいます。

1つのサーバで複数のクライアントを並列して捌くことで効率の良い処理が出来ると学びました。
そこで「マルチタスク」と「マルチプロセス」について学んだのですが、プロセスでは「親に子をコピーする」や、タスクでは「親と同じアドレス空間を扱うためコピーの必要がない」など、具体的なイメージがつかめていません。

私自身で単純なクライアントとサーバは作成できましたので、このサーバをどのように拡張すれば良いのかご説明を頂けませんでしょうか。
よろしくお願いします。

このクライアントとサーバは、「クライアントで入力した文字を、サーバで大文字に変換し、クライアントに送り返し表示させる」というプログラムです。

サーバ

コード:

#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include <unistd.h>
#include <sys/socket.h>
#include <arpa/inet.h>

#define SOCK_NAME "./socket"

/*argv[1]はポート番号*/

int main(int argc, char *argv[])
{
	int i;
	int fd1, fd2;
	struct sockaddr_in saddr;
	struct sockaddr_in caddr;

	int sPort;

	int len;
	int ret;
	char buf[1024];

	sPort = atoi(argv[1]);	//ポート番号を取得

	/*ソケット作成*/

	if( (fd1 =socket(AF_INET, SOCK_STREAM, 0)) < 0 )
	{
		perror("socket");
		exit(1);
	}

	memset((char *)&saddr, 0, sizeof(saddr));	//構造体を0で埋める
	saddr.sin_family = AF_INET;					//アドレスファミリ
	saddr.sin_addr.s_addr = htonl(INADDR_ANY);	//ワイルドカードを使用
	saddr.sin_port = htons(sPort);				//ポート番号


	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);
		}

		while( (ret = read(fd2, buf, 1024)) > 0 )//retに文字数を格納
		{
			for (i=0; i < ret; i++)
			{
				if (isalpha(buf[i]))	//文字かどうか判定
				{
					buf[i] = toupper(buf[i]);
				}
			}
			write(fd2, buf, 1024);
		}
		close(fd2);
	}
	close(fd1);

	return 0;
}
クライアント

コード:

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<unistd.h>
#include<sys/socket.h>
#include<arpa/inet.h>
#include<netinet/in.h>

#define SOCK_NAME "./socket"

/*argv[1]はIPアドレス, argv[2]はポート番号*/

int main(int argc, char *argv[])
{
	struct sockaddr_in saddr;
	int soc;
	char buf[1024];

	char *sIP;
	int sPort;

	sIP = argv[1];			//サーバのIPアドレスを取得
	sPort = atoi(argv[2]);	//ポート番号を取得

	/*ソケット作成*/

	if ( (soc = socket(AF_INET, SOCK_STREAM, 0) ) < 0 )
	{
		perror("socket");
		exit(1);
	}

	memset((char *)&saddr, 0, sizeof(saddr));	//saddrを0で埋める
	saddr.sin_family = AF_INET;					//アドレスファミリ
	saddr.sin_addr.s_addr = inet_addr(sIP);		//サーバのIPアドレス
	saddr.sin_port = htons(sPort);				//サーバのポート番号

	/*接続*/

	if( connect(soc, (struct sockaddr *)&saddr, sizeof(saddr) ) < 0)
	{
		perror("connect");
		exit(1);
	}

	/*小文字→大文字に変換*/

	printf("小文字を入力して下さい\n");

	while( fgets(buf, 1024, stdin) )
	{
		write(soc, buf, 1024);
		read(soc, buf, 1024);

		printf("大文字に変換します\n%s\n\n", buf);
		printf("小文字を入力して下さい\n");
	}
	close(soc);
	return 0;
}

たろ

Re: ソケットプログラミングのマルチプロセス・マルチタスクについて。

#2

投稿記事 by たろ » 12年前

Linux環境でかなり昔に学んだ内容です悪しからず。。
キーワードの紹介と、いま検索して見つけたサンプルコードが載ったサイトを紹介します。

複数のソケットを並列処理するプログラムの書き方はいろいろあります。
代表的なところでは以下の3種類くらいから入っていくとよいかなと思います。

(1) マルチプロセス方式
  fork関数で子プロセスを生成し、1つのソケットを1つのプロセスに処理させます。
  http://www.hayrodge.jp/?front=treedata% ... i=C&node=1
  http://www.infra.jp/programming/network ... ing_4.html

(2) マルチスレッド方式
  マルチプロセスと似ていますが、forkではなくpthread_createでスレッドを作り、1つのソケットを1つのスレッドに処理させます。
  http://www.hayrodge.jp/?front=treedata% ... i=C&node=1
  http://www.infra.jp/programming/network ... ing_5.html

(3) シングルスレッド方式
  select関数で複数ソケットを監視して、処理が必要なソケットを順次処理します。
  http://www.hayrodge.jp/?front=treedata% ... i=C&node=1
  http://www.infra.jp/programming/network ... ing_3.html
  ※select関数は古典的です。新しいpollやepoll関数が登場しています。

ちなみに「マルチタスク」という言い方はあまりしないと思います。

アバター
softya(ソフト屋)
副管理人
記事: 11677
登録日時: 15年前
住所: 東海地方
連絡を取る:

Re: ソケットプログラミングのマルチプロセス・マルチタスクについて。

#3

投稿記事 by softya(ソフト屋) » 12年前

補足的な回答です。
マルチタスクOSと俗に言いますが、PCで利用できるマルチタスクなOSではマルチプロセスと呼ばれることが多いです。
タスクと呼んでいるOSもありますが、Linux/Unix/Windows/MacOSXでは無い別のOSですね。
つまり、プロセスとタスクはほぼ同じ意味です。
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。

ツンドラ

Re: ソケットプログラミングのマルチプロセス・マルチタスクについて。

#4

投稿記事 by ツンドラ » 12年前

たろさん、softyaさんご回答ありがとうございます。返信遅くなって申し訳ありません。

たろさんに示してもらったURLをもとにもう一度見直して理解してみようと思います。
あと言葉の定義についても曖昧であることがわかったのでそちらも見直してみようと思います。

お二人ともありがとうございました。

閉鎖

“C言語何でも質問掲示板” へ戻る