---
# System prepended metadata

title: 網路程式設計 HW13

---

# 網路程式設計 HW13
## 第一題:基本群播程式
### 程式碼
#### Server端
```C++=
#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端
```C++=
#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端
```C++=
#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端
```C++=
#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;
}
```
## 心得
這個學期終於到了尾聲，在這堂課也學到了很多網路程設的相關知識，受益良多