---
# System prepended metadata

title: 1103757 喬伊波伊 網路程式設計 HW13

---

# 1103757 喬伊波伊 網路程式設計 HW13
## 練習1：
![](https://hackmd.io/_uploads/HyJzRw7U3.png)

server：
```cpp=
#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：
```cpp=
#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;
}

```
## 練習2：
![](https://hackmd.io/_uploads/HyKBCPXLn.png)

server：
```cpp=
#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){	
		cli.sin_addr.s_addr=inet_addr("224.111.1.1");
		cli.sin_port=htons(5678);
		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 的字串	
        
        cli.sin_addr.s_addr=inet_addr("224.111.1.2");
		cli.sin_port=htons(5678);
		memset(str, (i-1)%26 +'a', sizeof(str));
		sendto(serv_sd, str, strlen(str), 0,(LPSOCKADDR)&cli,cli_len);
        printf("server multicast: %s\n",str);		// 顯示送去client 的字串
        
        cli.sin_addr.s_addr=inet_addr("224.111.1.3");
		cli.sin_port=htons(5678);
		memset(str, (i-1)%26 +'A', 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：
```cpp=
#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];
char 		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);//由echo server接收
		if(n>0)
			printf("client(from：%s)：%s,%d\n",inet_ntoa(cli.sin_addr),str,n); 
	}
}

int main() {  
   
   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");
   
   cli.sin_family       = AF_INET;
   cli.sin_addr.s_addr  = 0;
   cli.sin_port         = htons(BROADCAST);
   
  	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.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");

 	
	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)))
					printf("setsockopt() 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)))
					printf("setsockopt() 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)))
					printf("setsockopt() 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)))
					printf("setsockopt() 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)))
					printf("setsockopt() 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)))
					printf("setsockopt() failed");
				break;
		}
		  
	}
	
  	closesocket(sd); //關閉 socket
    WSACleanup();  // 結束 WinSock DLL 的使用
   
   	return 0;
}
```
## 心得：老師作業那編寫練習1-5但影片只有練習1-2，阿終於結束了，很累都沒時間好好念書，下學期真的要好好拿捏作業的量。