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