/********************************************************************** Winsock2を用いたEchoサンプルプログラム このサンプルプログラムはサーバに文字列をリプライさせます。 (1)サーバ名はEchoプロトコルを受け付けるサーバ名を指定してください。 (2)コンパイル時に「ws2_32.lib」をリンクしてください。 **********************************************************************/
#define REQUEST_INFO const char
*servername="aaaa.tokyo-ct.ac.jp";
/* Import Library: Link with
ws2_32.lib */ #include <stdio.h> #include
<string.h> #include <winsock2.h>
/*ソケットsに文字列データdataを送信する関数*/ void
sendData(SOCKET s, char *data) {
send(s,data,strlen(data),0); }
/*ソケットsからバッファサイズbuffsizeのデータバッファdatabuffに データを受け取る関数 返す値は取得バイト数*/ int
receiveData(SOCKET s, char *databuff, int
buffsize) { char
*p=databuff; int i; for
(i=0;i<buffsize;i++) *p++=0; return
recv(s,databuff,buffsize,0); }
/**************** for printing
information HEAD ************************/ #ifdef
REQUEST_INFO void printWinsockInfo(WSADATA
*wsaData) { union
{ short int
s; unsigned char
c[2]; } v,hv; if
(wsaData==NULL) return;
v.s=wsaData->wVersion;
hv.s=wsaData->wHighVersion; printf("== winsock
information ==\n"); printf("winsock
version = %d.%d\n",v.c[0],v.c[1]);
printf("winsock HighVer =
%d.%d\n",hv.c[0],hv.c[1]);
printf("Description =
%s\n",wsaData->szDescription);
printf("SystemStatus = %s\n"
,wsaData->szSystemStatus); printf("Max
Sockets = %d\n"
,wsaData->iMaxSockets); printf("Max UDP byte size
= %d\n" ,wsaData->iMaxUdpDg);
printf("\n"); } void printServerInfo(LPHOSTENT
lpHost) { int i; if
(lpHost==NULL) return; printf("== server information
==\n"); printf("host
name = %s\n" ,
lpHost->h_name); printf("address type
= %d\n" , lpHost->h_addrtype); /*AF_INETは2*/
printf("address length = %d\n" ,
lpHost->h_length); for(i = 0 ;
lpHost->h_aliases[i] ; i++)
{
printf("aliases = %s\n" ,
lpHost->h_aliases[i]); }
for(i = 0 ;
lpHost->h_addr_list[i] ; i++)
{ IN_ADDR
*ip; ip = (IN_ADDR
*)lpHost->h_addr_list[i];
printf("IP address = %s\n" ,
inet_ntoa(*ip)); }
printf("\n"); } void printServiceInfo(LPSERVENT
lpServ) { int i; if
(lpServ==NULL) return; printf("== service
information ==\n"); printf("service name = %s\n" ,
lpServ->s_name); for(i = 0 ;
lpServ->s_aliases[i] ; i++)
{
printf("aliases = %s\n" ,
lpServ->s_aliases[i]);
} printf("port number = %d\n" ,
lpServ->s_port);
printf("protocol = %s\n" ,
lpServ->s_proto); printf("\n"); } void
printPortInfo(int port) { printf("== port number
information ==\n"); printf("port number = %d\n" ,
ntohs((short)port));
/*ntohsはホストバイトオーダーに戻す関数*/
printf("\n"); } #endif /**************** for printing
information TAIL ************************/
/************************************************************ ソケットをオープンし,目的のサーバのポートに接続する server:
サーバの名前(ドメイン名,ドメインを省略してはいけない)
例えばaaaa.tokyo-ct.ac.jp servicename:"smtp"とか"http"などのサービスの名前,
次のところに名前の一覧がある
Windowsシステムのsystem32\drivers\etc\services service:
サービスのポート番号,smtpなら25,httpなら80など
この情報は,servicenameが不明の場合に必要なだけで,
通常は使われない 不成功ならINVALID_SOCKETを返す *************************************************************/ SOCKET
connectSocket(const char *server, char *servicename, short int
service) { WSADATA wsaData;
/*winsock*/ LPHOSTENT lpHost;
LPSERVENT lpServ; SOCKET sock;
SOCKADDR_IN sockAddr; int port;
/*ポート番号*/ int status;
/*winsockをver1.1で初期化を要求*/
status=WSAStartup(MAKEWORD(1, 1), &wsaData); if
(status != 0) {
fprintf(stderr,"WSAStartup()
failed\n"); return
INVALID_SOCKET; }
/*サーバ名からホストの情報を得る*/ lpHost =
gethostbyname(server); if(lpHost == NULL)
{ fprintf(stderr,"server
name error\n");
WSACleanup(); return
INVALID_SOCKET; }
/*サービス情報からポート番号取得*/ lpServ =
getservbyname(servicename, NULL); if (lpServ ==
NULL) {
port=htons(service);
/*ホストバイトオーダーからネットワークバイトオーダー(ビッグエンディアン)に変換*/ } else
{
port=lpServ->s_port; }
#ifdef REQUEST_INFO
/*情報要求がある場合(学習のため)*/
printWinsockInfo(&wsaData);
/*Winsocの情報表示*/
printServerInfo(lpHost);
/*サーバの情報表示*/
printServiceInfo(lpServ);
/*サービスの情報表示*/
printPortInfo(port);
/*ポート番号の情報表示*/ #endif
/*ソケットオープン*/ sock = socket(PF_INET, SOCK_STREAM,
0); if (sock == INVALID_SOCKET)
{ fprintf(stderr,"socket()
error\n");
WSACleanup(); return
INVALID_SOCKET; }
/*ソケット結合*/ sockAddr.sin_family =
AF_INET; sockAddr.sin_port =
port; sockAddr.sin_addr =
*((LPIN_ADDR)*lpHost->h_addr_list);
status=connect(sock, (PSOCKADDR)&sockAddr,
sizeof(SOCKADDR_IN)); if (status)
{ fprintf(stderr,"connect()
error\n");
closesocket(sock);
WSACleanup(); return
INVALID_SOCKET; } return
sock; }
#define sndBufSize 1024 #define rcvBufSize
1024
/*サーバにDayTimeプロトコルでリプライさせる*/ int getEcho(const
char *server) { SOCKET
sock; static char
sndBuf[sndBufSize],rcvBuf[rcvBufSize];
/*ECHOサーバへの接続*/
sock=connectSocket(server,"echo",IPPORT_ECHO); if
(sock == INVALID_SOCKET) return 1;
printf("connecting Socket\n");
/*サーバへの文字列送信とリプライ受信*/ sprintf(sndBuf,"Hello from
Tokyo.\r\n"); sendData(sock,
sndBuf);
receiveData(sock,rcvBuf,rcvBufSize);
printf("sending : %s",sndBuf);
printf("receiving : %s\n",rcvBuf);
/*サーバへの文字列送信とリプライ受信*/ sprintf(sndBuf,"Seeing is
believing.\r\n"); sendData(sock,
sndBuf);
receiveData(sock,rcvBuf,rcvBufSize);
printf("sending : %s",sndBuf);
printf("receiving : %s\n",rcvBuf);
closesocket(sock);
WSACleanup(); return 0; }
int main() {
getEcho(servername); return
0; } |