2014年1月5日日曜日

MinGW socket programming in C

RDCSのネットワーク部分は、HTTPで実装してきたのだが、

やはり、性能などの点で問題があり、Client-Serverに戻すことにしました。

性能と、拡張性を確保するために変更します。

将来的な事を考えて、従来Winodws上で構築していたが、MinGW環境実装するように変更する。

基本的に確認しなければならないのは、2点で、

(1) Socketを使った、プログラムの確認

(2) (1)とthreadを組合わせた場合の挙動

で、最初に(1)をしました。

大丈夫だと思うは、コンピュータの世界は通用しないもんね。

重要なポイントは、次の3点に集約できる。その点を理解すれば、イイチャ。

a. MinGWは、winsockを使ってネットワークを実装しているので、おまじないが必要

b. 変数の型

c. リンクモジュール


a. おまじない
     ・include
         #include <winsock2.h>
         #include <ws2tcpip.h>

         通常の #include <sys/socket.h>,<netinet.h>などは使わない

     ・モジュールの初期化が必要

         変数宣言      WSADATA wsaData;

         初期化         WSAStartup(MAKEWORD(2 ,0), &wsaData);

         終了処理     closesocket(SOCKET  ss);

                           WSACleanup();

b. 変数宣言

       SOCKET を使う。POSIXは、int の descriptor 

         従って、read、writeは使えない。recvとsendを使う。
           
c. リンクモジュール

       -lwsock32 -lws2_32

以上です。   で、 serverとclientのテスト用モジュールをドーン

Peace!!

/***********************************************************
** Function : RDCS network system Server test
** File Name: server.c
** Library  :
** Author   :
** create   :
** modify   :
***********************************************************/
//----------------------------------------------------------
// Includes
//----------------------------------------------------------#include <stdio.h>
#include <stdio.h>
#include <sys/types.h>
#include <winsock2.h>
#include <ws2tcpip.h>
//#include <sys/socket.h>
//#include <netinet/in.h>
#include <errno.h>

//----------------------------------------------------------
// Defines
//----------------------------------------------------------
#define _POSIX_SOURCE  1   /* POSIX comliant source (POSIX)*/
#define BUFFSIZE       256
#define FALSE          0
#define TRUE           1

//----------------------------------------------------------
// Globals
//----------------------------------------------------------

//----------------------------------------------------------
// Prototype
//----------------------------------------------------------
int main();

/***********************************************************
** Function :
** Category :
** Parameter:
**          :
** ---------------------------------------------------------
** return   : normal end :0
**          : error      : -1  error progess is upper routine.
** note     :
**          :
************************************************************/
int main()
{
WSADATA wsaData;
SOCKET sock;
SOCKET sock0;

struct sockaddr_in addr;
struct sockaddr_in client;

//int sock0;
//int sock;

int len;
int n;
/*******************************************************
** Initialize
********************************************************/
if (WSAStartup(MAKEWORD(2 ,0), &wsaData) == SOCKET_ERROR) {
printf ("Error initialising WSA.\n");
return -1;
}

/*******************************************************
** Process
*******************************************************/
//------------------------------------------------------
// (1) Open Socket
//------------------------------------------------------
sock0 = socket(AF_INET, SOCK_STREAM, 0);
if (sock0 < 0) {
perror("socket");
printf("%d\n", errno);
return 1;
}
printf("after scoket\n");

//------------------------------------------------------
// (2) bind
//------------------------------------------------------
addr.sin_family = AF_INET;
addr.sin_port = htons(50000);
addr.sin_addr.s_addr = INADDR_ANY;

if (bind(sock0, (struct sockaddr *)&addr, sizeof(addr)) != 0) {
perror("bind");
return 1;
}

//------------------------------------------------------
// (3) listen
//------------------------------------------------------
if (listen(sock0, 5) != 0) {
perror("listen");
return 1;
}

//------------------------------------------------------
// (4) accept
//------------------------------------------------------
while (1) {
len = sizeof(client);
sock = accept(sock0, (struct sockaddr *)&client, &len);
if (sock < 0) {
perror("accept");
break;
}

n = send(sock, "RDCS SERVER", 11, 0);

if (n < 1) {
perror("write");
break;
}

//close(sock);
closesocket(sock);
}

/*******************************************************
** Terminate
*******************************************************/
//close(sock0);
closesocket(sock0);
WSACleanup();

return 0;
}



/***********************************************************
** Function : RDCS network system Client test
** File Name: client1.c
** Library  : 
** Author   : 
** create   : 
** modify   :
***********************************************************/
//----------------------------------------------------------
// Includes
//----------------------------------------------------------
#include <stdio.h>
#include <sys/types.h>
#include <winsock2.h>
#include <ws2tcpip.h>
//#include <sys/socket.h>
//#include <netinet/in.h>
//#include <arpa/inet.h>
//#include <netdb.h>

//----------------------------------------------------------
// Defines
//----------------------------------------------------------
#define _POSIX_SOURCE  1   /* POSIX comliant source (POSIX)*/
#define BUFFSIZE       256
#define FALSE          0
#define TRUE           1

//----------------------------------------------------------
// Globals
//----------------------------------------------------------

//----------------------------------------------------------
// Prototype
//----------------------------------------------------------
int main(int argc, char *argv[]);

//----------------------------------------------------------
// Code
//----------------------------------------------------------

/***********************************************************
** Function : 
** Category : 
** Parameter: 
**          : 
** ---------------------------------------------------------
** return   : normal end :0
**          : error      : -1  error progess is upper routine.
** note     : 
**          :
************************************************************/
int main(int argc, char *argv[])
{
WSADATA wsaData;
SOCKET sock;
struct sockaddr_in server;
//int sock;
char buf[32];
char *deststr;
unsigned int **addrptr;

/*******************************************************
** Initialize 
********************************************************/
if (argc != 2) {
printf("Usage : %s dest\n", argv[0]);
return 1;
}
deststr = argv[1];
if (WSAStartup(MAKEWORD(2,0), &wsaData) == SOCKET_ERROR) {
printf ("Error initialising WSA.\n");
return -1;
}

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

/*******************************************************
** Process 
*******************************************************/
//------------------------------------------------------
// (1)
//------------------------------------------------------
server.sin_family = AF_INET;
server.sin_port = htons(50000);
server.sin_addr.s_addr = inet_addr(deststr);

//------------------------------------------------------
// (2)connect
//------------------------------------------------------
if (connect(sock, (struct sockaddr *)&server, sizeof(server)) != 0) {
perror("connect");
return 1;
}

//------------------------------------------------------
// (3)
//------------------------------------------------------
char vect[512]={0};
int get=recv(sock,vect,512,0);
printf("read=%s\n", vect);
/*******************************************************
** Terminate 
*******************************************************/
//close(sock);
closesocket(sock);
WSACleanup();

return 0;
}


//EOM

1 件のコメント:

  1. 上記ご記載の内容をURLおよびクレジットを表示の上で、全文引用させて頂きたいのですが、ご許諾を頂くことは可能でしょうか。ソースコードも含めて有用なメモとして手元に置いておきたいと考えております。

    返信削除