# 1103757 喬伊波伊 網路程式設計 HW13
## 練習1:

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:

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,阿終於結束了,很累都沒時間好好念書,下學期真的要好好拿捏作業的量。