Try   HackMD

網路程式設計 HW13

第一題:基本群播程式

程式碼

Server端

#include <stdio.h> #include <string.h> #include <winsock.h> #define MAXLINE 20 /* 字串緩衝區長度 */ int main() { SOCKET serv_sd; /* socket 描述子 */ int cli_len, n,i=1; char str[MAXLINE]; struct sockaddr_in serv, cli; WSADATA wsadata; WSAStartup(0x101, &wsadata); //呼叫 WSAStartup() 註冊 WinSock DLL 的使用 serv_sd=socket(AF_INET, SOCK_DGRAM, 0);// 開啟 UDP socket /* Set TTL of multicast packet */ int multicastTTL=1; if (setsockopt(serv_sd, IPPROTO_IP, IP_MULTICAST_TTL, (char *) &multicastTTL, sizeof(multicastTTL)) == SOCKET_ERROR) printf("setsockopt() failed"); cli_len = sizeof(cli); printf("server will multicastcast.\n"); cli.sin_family = AF_INET; cli.sin_addr.s_addr = inet_addr("224.1.1.1"); cli.sin_port = htons(5678); while(1){ memset(str, i%10 +'0', sizeof(str)); sendto(serv_sd, str, strlen(str), 0,(LPSOCKADDR)&cli,cli_len); printf("server multicast: %s\n",str); // 顯示送去client 的字串 Sleep(1000); i++; } //結束 WinSock DLL 的使用 closesocket(serv_sd); //closesocket(cli_sd); WSACleanup(); }

Client端

#include <stdio.h> #include <string.h> #include <winsock.h> #define MAXLINE 1024 int main() { SOCKET sd; struct sockaddr_in serv,cli; char str[1024]; WSADATA wsadata; int n,serv_len; int flag=1,len=sizeof(int); WSAStartup(0x101,(LPWSADATA) &wsadata); // 呼叫 WSAStartup() 註冊 WinSock DLL 的使用 sd=socket(AF_INET, SOCK_DGRAM, 0); if ( setsockopt(sd, SOL_SOCKET, SO_REUSEADDR, (const char*)&flag, len) < 0 ) printf("setsockopt() failed"); cli.sin_family = AF_INET; cli.sin_addr.s_addr = 0; cli.sin_port = htons(5678); if( bind(sd, (LPSOCKADDR) &cli, sizeof(cli)) <0 ) printf("bind error!\n"); struct ip_mreq multicastRequest; /* Multicast address join structure */ /* Specify the multicast group */ multicastRequest.imr_multiaddr.s_addr = inet_addr("224.1.1.1"); /* Accept multicast from any interface */ multicastRequest.imr_interface.s_addr = htonl(INADDR_ANY); /* Join the multicast address */ if (setsockopt(sd, IPPROTO_IP, IP_ADD_MEMBERSHIP, (const char *) &multicastRequest,sizeof(multicastRequest)) < 0) printf("setsockopt() failed"); serv_len=sizeof(serv); while(1){ n=recvfrom(sd, str, MAXLINE, 0,(LPSOCKADDR) &serv,&serv_len ); //由echo server接收 str[n]='\0'; printf("client(from:%s):%s\n",inet_ntoa(serv.sin_addr),str); } closesocket(sd); //關閉 socket WSACleanup(); // 結束 WinSock DLL 的使用 return 0; }

第二題: 多頻道

程式碼

Server端

#include <stdio.h> #include <string.h> #include <winsock.h> #define MAXLINE 20 /* 字串緩衝區長度 */ int main() { SOCKET sd; /* socket 描述子 */ int cli_len, n,i=1; char str[MAXLINE]; struct sockaddr_in serv, cli; WSADATA wsadata; WSAStartup(0x101, &wsadata); //呼叫 WSAStartup() 註冊 WinSock DLL 的使用 sd=socket(AF_INET, SOCK_DGRAM, 0);// 開啟 UDP socket /* Set TTL of multicast packet */ int multicastTTL=1; if (setsockopt(sd, IPPROTO_IP, IP_MULTICAST_TTL, (char *) &multicastTTL, sizeof(multicastTTL)) == SOCKET_ERROR) printf("setsockopt() failed"); cli_len = sizeof(cli); printf("server will multicastcast.\n"); cli.sin_family = AF_INET; cli.sin_addr.s_addr = inet_addr("224.1.1.1"); cli.sin_port = htons(5678); while(1){ cli.sin_addr.s_addr=inet_addr("224.1.1.1"); cli.sin_port=htons(5678); memset(str,i%10+'0',sizeof(str)); sendto(sd,str,strlen(str),0,(LPSOCKADDR)&cli,cli_len); printf("server multicast: %s\n",str); cli.sin_addr.s_addr=inet_addr("224.1.1.2"); cli.sin_port=htons(5678); memset(str,(i-1)%26+'a',sizeof(str)); sendto(sd,str,strlen(str),0,(LPSOCKADDR)&cli,cli_len); printf("server multicast: %s\n",str); cli.sin_addr.s_addr=inet_addr("224.1.1.3"); cli.sin_port=htons(5678); memset(str,(i-1)%26+'A',sizeof(str)); sendto(sd,str,strlen(str),0,(LPSOCKADDR)&cli,cli_len); printf("server multicast: %s\n",str); Sleep(1000); i++; } //結束 WinSock DLL 的使用 closesocket(sd); //closesocket(cli_sd); WSACleanup(); }

Client端

#include <stdio.h> #include <string.h> #include <pthread.h> #include <winsock.h> #define MAXLINE 1024 #define BROADCAST 5678 SOCKET sd; struct sockaddr_in serv,cli; char str[1024],str_r[1024]; WSADATA wsadata; int timeout=50,n,serv_len,cli_len,channel=1; int flag=1,len=sizeof(int); void *recvMess(void* argu){ while(1){ cli_len=sizeof(cli); n=recvfrom(sd,str,MAXLINE,0,(LPSOCKADDR)&cli,&cli_len); if (n>0) printf("Client(from:%s):%s,%d\n",inet_ntoa(cli.sin_addr),str,n); } } int main(void) { int n,i,j,total=0; pthread_t thread1; WSAStartup(0x101,(LPWSADATA) &wsadata); // 呼叫 WSAStartup() 註冊 WinSock DLL 的使用 sd=socket(AF_INET, SOCK_DGRAM, 0); if ( setsockopt(sd, SOL_SOCKET, SO_REUSEADDR, (const char*)&flag, len) < 0 ) printf("setsockopt() failed"); serv.sin_family = AF_INET; serv.sin_addr.s_addr = 0; serv.sin_port = htons(5678); if( bind(sd, (LPSOCKADDR) &cli, sizeof(cli)) <0 ) printf("bind error!\n"); serv_len=sizeof(serv); pthread_create(&thread1,NULL,&recvMess,NULL); struct ip_mreq multicastRequest; /* Multicast address join structure */ /* Specify the multicast group */ multicastRequest.imr_multiaddr.s_addr = inet_addr("224.111.1.1"); /* Accept multicast from any interface */ multicastRequest.imr_interface.s_addr = htonl(INADDR_ANY); /* Join the multicast address */ while(1){ scanf("%d",&channel); printf("switch to channel %d\n\n",channel); switch(channel){ case 1: multicastRequest.imr_multiaddr.s_addr=inet_addr("224.111.1.1"); if(setsockopt(sd, IPPROTO_IP, IP_ADD_MEMBERSHIP, (const char*)&multicastRequest,sizeof(multicastRequest)) < 0) printf("setsockpt() failed"); break; case 2: multicastRequest.imr_multiaddr.s_addr=inet_addr("224.111.1.1"); if(setsockopt(sd, IPPROTO_IP, IP_DROP_MEMBERSHIP, (const char*)&multicastRequest,sizeof(multicastRequest)) < 0) printf("setsockpt() failed"); break; case 3: multicastRequest.imr_multiaddr.s_addr=inet_addr("224.111.1.2"); if(setsockopt(sd, IPPROTO_IP, IP_ADD_MEMBERSHIP, (const char*)&multicastRequest,sizeof(multicastRequest)) < 0) printf("setsockpt() failed"); break; case 4: multicastRequest.imr_multiaddr.s_addr=inet_addr("224.111.1.2"); if(setsockopt(sd, IPPROTO_IP, IP_DROP_MEMBERSHIP, (const char*)&multicastRequest,sizeof(multicastRequest)) < 0) printf("setsockpt() failed"); break; case 5: multicastRequest.imr_multiaddr.s_addr=inet_addr("224.111.1.3"); if(setsockopt(sd, IPPROTO_IP, IP_ADD_MEMBERSHIP, (const char*)&multicastRequest,sizeof(multicastRequest)) < 0) printf("setsockpt() failed"); break; case 6: multicastRequest.imr_multiaddr.s_addr=inet_addr("224.111.1.3"); if(setsockopt(sd, IPPROTO_IP, IP_DROP_MEMBERSHIP, (const char*)&multicastRequest,sizeof(multicastRequest)) < 0) printf("setsockpt() failed"); break; } } closesocket(sd); //關閉 socket WSACleanup(); // 結束 WinSock DLL 的使用 return 0; }

心得

這個學期終於到了尾聲,在這堂課也學到了很多網路程設的相關知識,受益良多