ipv6 網路程式設計 ( tcp client/server)
DESCRIPTION
IPv6 網路程式設計 ( TCP Client/Server). 授課老師:陳懷恩 助教:邱俊傑、江鴻毅、朱健隴 國立宜蘭大學 資訊工程研究所. 課程目標. 教同學 們 使用 Microsoft Visual Studio 2008 以及 C 語言寫出 IPv6 TCP 的 Server 端與 Client 端 程式. TCP Client-Server 建構流程圖. 1. 建立 Socket( 使用 Socket() 函數 ). 2. 連結 Socket( 使用 bind() 函數 ). 3. 開啟 listening socket. - PowerPoint PPT PresentationTRANSCRIPT
IPv6 網路程式設計(TCP Client/Server)
授課老師:陳懷恩助教:邱俊傑、江鴻毅、朱健隴國立宜蘭大學 資訊工程研究所
1
課程目標教同學們使用 Microsoft Visual Studio 2008以及 C 語言寫出 IPv6 TCP 的 Server 端與 Client 端 程式
2
TCP Client-Server 建構流程圖
關閉 Socket( 使用 close()函數 )
1. 建立 Socket( 使用 Socket() 函數 )
2. 使用 Connect() 函 數連線要求3. Send() 函數送出 資料給 Server
4. 使用 recv() 接收 資料
1. 建立 Socket( 使用 Socket() 函數 )
2. 連結 Socket( 使用 bind() 函數 )
3. 開啟 listening socket
4. 等待接受 Client 端連線 要求
5. 使用 recv() 接收資料
6. send() 函數送出
連線要求TCP three-way handshake
Socket()
Bind()
Listen()
Accept()
recv()
Send()
Socket()
Connect()
Send()
recv() 資料
資料
TCP Server
TCP Client
3
程式宣告◦ #include <winsock2.h>
// 連結 WinSock 基本函式◦ #include <stdio.h>
// 連結 C 基本輸入輸出函式◦ #include <ws2tcpip.h>
// 連結微軟所提供的 TCP/IP 基本函式◦ #pragma comment(lib, "WS2_32.lib")
// 連結 Wsock32.lib 資料庫
TCP Server 端程式 (1/7)
4
主程式 - 宣告 void main()
{◦ int FromLen; // 宣告一個儲存長度的變數◦ char *Address ="2001:e10:1440:1:5003:317f:8e8d:dc58"; ◦ char *Port = "5001"; // 宣告 Server 的 port ◦ char Buffer[1024] = ""; // 宣告 Buffer 大小為 1024 位元◦ADDRINFO Hints, *AddrInfo;
// 宣告 Hints 與 *AddrInfo 資料結構◦ SOCKADDR_STORAGE From; // 宣告 From◦ SOCKET ServSock, msgsock; // 宣告接收和發送的 Sockets
TCP Server 端程式 (2/7)
5
這個部分請同學填寫伺服器的 IPv6位址
主程式 - 呼叫指定的 Winsock DLL◦WORD wVersionRequested;◦wVersionRequested = MAKEWORD( 2, 2 );
// Socket 最高的版本。// 高位指定次要版本 ; 低位指定主要版本。
◦WSADATA wsaData;// 這個結構被用於存放初始化數據到 WSAStartup 。
◦WSAStartup( wVersionRequested, &wsaData );
此為微軟系統中必要呼叫 Socket 程式之固定寫法
TCP Server 端程式 (3/7)
6
主程式 -Hints◦ memset(&Hints, 0, sizeof(Hints)); // 清除 Hints 記憶體◦ Hints.ai_family = PF_INET6; // 選擇使用 IPv6◦ Hints.ai_socktype = SOCK_STREAM;// 選擇使用 TCP◦ Hints.ai_flags = AI_NUMERICHOST | AI_PASSIVE; //AI_NUMERICHOST 是將旗標設定為二進位 (101) // AI_PASSIVE 是將旗標設定為 bind() 中使用位址返回函數◦ getaddrinfo(Address,Port,&Hints,&AddrInfo); // 將 Address 與 Port 寫入 AddrInfo
TCP Server 端程式 (4/7)
7
主程式 - 建立 Socket◦ ServSock=socket(PF_INET6, SOCK_STREAM,0); // 建立 Server 端 Socket 使用 IPv6 與 TCP◦ if(bind(ServSock,AddrInfo->ai_addr,AddrInfo->ai_addrlen) >=
0 ); // 綁定 Socket 於 AddrInfo 所指定的 IP 位址◦ printf("bind TCP_V6 OK\n"); // 顯示字串◦ listen(ServSock, 5); // 設定可連入 5 個連線◦ FromLen=sizeof(From); // 設定 sockaddr 長度
TCP Server 端程式 (5/7)
8
printf() 是輸出輸入函式庫中的函式
主程式 - 迴圈 while(1){◦msgsock=accept(ServSock, (LPSOCKADDR) & From,&FromLen); //msgsock 為接受 Client 連入的 Socket
//(ServSock 的 SOCKET, 自己的位置 Form,Form 的長度 )◦ printf("accept new socket \n"); // 顯示 "accept new socket" 字串◦ recv(msgsock,Buffer,1024,0);
// 接收 msgsock 傳入資料存入 Buffer◦ printf("Server 收到 :%s\n", Buffer); // 顯示 Buffer 中儲存的字串◦ send(msgsock, Buffer, sizeof(Buffer), 0);
// 回傳 Buffer 中的資料給 Client}
TCP Server 端程式 (6/7)
9
主程式 - 結束◦ closesocket(msgsock);
// 關閉 Client Socket◦WSACleanup(); // 清空回傳值}
TCP Server 端程式 (7/7)
10
可與WSAStartup()函式相呼應 (第 6頁 )
結束先前建立的 socket
程式宣告◦ #include <winsock2.h>
// 連結 WinSock 基本函式◦ #include <stdio.h>
// 連結 C 基本輸入輸出函式◦ #include <ws2tcpip.h>
// 連結微軟提供的 TCP/IP 基本函式◦ #pragma comment(lib, "WS2_32.lib")
// 連結 Wsock32.lib 資料庫
TCP Client 端程式 (1/8)
11
同學注意到了嗎 ?這個部分與 Server端程式相同。
主程式 - 宣告 void main()
{◦ char *Server = "2001:e10:1440:1:5003:317f:8e8d:dc58";
// 指定 Server IPv6 位址◦ char *Port = "5001"; // 指定 Server 的 port 為 5001 ◦ char recvbuffer[1024]; // 宣告接收站存區大小為 1024 位元◦ADDRINFO Hints, *AddrInfo;
// 宣告 Hints 與 *AddrInfo 資料結構
TCP Client 端程式 (2/7)
12
這個部分請同學填寫你要連線的電腦IPv6位址
主程式 - 呼叫指定的 Winsock DLL◦WORD wVersionRequested;◦wVersionRequested = MAKEWORD( 2, 2 );
// Socket 最高的版本。// 高位指定次要版本 ; 低位指定主要版本。
◦WSADATA wsaData;// 這個結構被用於存放初始化數據到 WSAStartup 。
◦WSAStartup( wVersionRequested, &wsaData );
此為微軟系統中必要呼叫 Socket 程式之固定寫法
TCP Client 端程式 (3/7)
13
這個部分與 Server端程式相同
主程式 -Hints◦ memset(&Hints,0,sizeof(Hints)); // 清除 Hints 記憶體◦ Hints.ai_family = PF_INET6; // 選擇使用 IPv6◦ Hints.ai_socktype = SOCK_STREAM;// 選擇使用 TCP◦ getaddrinfo(Server ,Port,&Hints,&AddrInfo);// 取得到位址與 PORT 號並轉換 ANSI host 名稱為一個可用的位址
TCP Client 端程式 (4/7)
14
這個部分與 Server端程式相同
主程式 - 建立 SOCKET ◦ SOCKET sockClient;
// 宣告一個名為 sockClient 的 SOCKET 主程式 - 迴圈 while(1){◦ sockClient = socket( PF_INET6, SOCK_STREAM, 0 ) ;
// 取得到伺服器位址與 port 號◦ connect(sockClient,AddrInfo->ai_addr, AddrInfo-
>ai_addrlen);// 連結到 sockClient 的位置 , 位置長度 ( 寫入 while 可讓程式一直和 server 持續進行 )
◦ char buffer[1024]=""; // 宣告發送資料的長度
TCP Client 端程式 (5/7)
15
◦ printf("input message:");// 顯示 input message:◦ scanf("%s",buffer);// 輸入的字串填入 buffer◦ send(sockClient,buffer ,sizeof(buffer), 0);
// 送出 buffer 中的資料 ( 使用者輸入的 )// sockClient 的資料為 buffer, 長度 ,0
◦ recv(sockClient,recvbuffer, sizeof(recvbuffer), 0); // 接收 Server 回傳的資料// 資料儲存於 recvbuffer 中
◦ printf("Receive:%s\n",recvbuffer);// 顯示接收到字串
}
TCP Client 端程式 (6/7)
16
主程式 - 結束◦ closesocket(sockClient);
// 關閉 Client Socket◦WSACleanup(); // 清空回傳值}
TCP Client 端程式 (7/7)
17
結束 Socket ,這個部分與 Server端程式相同。
助教將於課堂上公布 Server IP 位址 Server Port 為 5001 請同學寫出 IPv6 TCP Client 端 程式 輸入學號發送到 Server 端 助教確認正確收到即算完成作業
課堂作業 01
18
IPv6 網路程式設計(UDP Client/Server)
授課老師:陳懷恩助教:邱俊傑、江鴻毅、朱健隴國立宜蘭大學 資訊工程研究所
19
課程目標教同學們使用 Microsoft Visual Studio 2008以及 C 語言寫出 IPv6 UDP 的 Server 端與 Client 端程式
20
UDP Client-Server 建構流程圖
1. 建立 Socket( 使用 Socket 函數 )
2. 以 Sendto() 函數傳送資料 給 Server 端3. 以 recvfrom() 函數接收 Server 端傳來的資料 4. 關閉 Socket( 使用 Close () 函數 )
1. 建立 Socket( 使用 Socket 函數 )
2. 連結 Socket( 使用 bind 函數 )
3. 以 recvfrom() 函數接 收 Client 端傳來的資 料
4. 以 Sendto() 函數傳送資 料給 Client 端5. 關閉 Socket( 使用 Close () 函數 )
Socket()
Bind()
Recvfrom()
等待資料接收
Sendto()
Socket()
Sendto()
Recvfrom()
Close()
UDP Server
UDP Client
回覆資料
送出資料
21
程式宣告◦ #include <winsock2.h>
// 連結 WinSock 基本函式◦ #include <stdio.h>
// 連結 C 基本輸入輸出函式◦ #include <ws2tcpip.h>
// 連結微軟所提供的 TCP/IP 基本函式◦ #pragma comment(lib, "WS2_32.lib")
// 連結 Wsock32.lib 資料庫
UDP Server 端程式 (1/7)
22
主程式 - 宣告 void main()
{◦ char *Server= "2001:e10:1440:1:5003:317f:8e8d:dc58"; ◦ char *Port= "5001"; // 宣告 Server 的 port◦ char recvBuf[1024]; // 宣告 Buffer 大小為 1024 位元◦ADDRINFO Hints, *AddrInfo;
// 宣告 Hints 與 *AddrInfo 資料結構◦SOCKADDR_STORAGE From;
// 宣告 From 為一個 SOCKADDR_STORAGE 的結構
UDP Server 端程式 (2/7)
23
這個部分請同學填寫伺服器的 IPv6位址
主程式 - 呼叫指定的 Winsock DLL◦WORD wVersionRequested;◦wVersionRequested = MAKEWORD( 2, 2 );
// Socket 最高的版本。// 高位指定次要版本 ; 低位指定主要版本。
◦WSADATA wsaData;// 這個結構被用於存放初始化數據到 WSAStartup 。
◦WSAStartup( wVersionRequested, &wsaData );
此為微軟系統中必要呼叫 Socket 程式之固定寫法
UDP Server 端程式 (3/7)
24
主程式 -Hints◦memset(&Hints,0,sizeof(Hints));// 清除 Hints 記憶體◦Hints.ai_family = PF_INET6;// 選擇使用 IPv6◦Hints.ai_socktype=SOCK_DGRAM;// 選擇使用 UDP◦ getaddrinfo(Server,Port,&Hints,&AddrInfo);
// 取得到位址與 PORT 號並轉換 ANSI host 名稱為一個可用的位址
UDP Server 端程式 (4/7)
25
主程式 - 建立 SOCKET◦SOCKET sockSrv=socket(PF_INET6,SOCK_DGRAM, 0);
// 取得到伺服器位址與 port 號
◦ bind(sockSrv, AddrInfo->ai_addr, AddrInfo->ai_addrlen);// 綁定 Socket 於某個 IP 位址
◦ printf("bind UDP_v6 OK\n"); // 顯示 bind UDP_v6 OK◦ int len=sizeof(From); // 宣告 len 為 sockaddr 長度
UDP Server 端程式 (5/7)
26
主程式 - 迴圈 while(1){◦ recvfrom(sockSrv,recvBuf,sizeof (recvBuf),0,
(LPSOCKADDR)&From,&len);◦ printf("%s\n",recvBuf);
// 顯示接收到字串◦ sendto(sockSrv, recvBuf, sizeof (recvBuf),0,
(LPSOCKADDR)&From,sizeof (From));◦ printf("ACK %s\n",recvBuf);
// 顯示傳送到字串}
UDP Server 端程式 (6/7)
27
主程式 - 結束◦ closesocket(sockSrv);
// 關閉 Client Socket◦WSACleanup();
// 清空回傳值}
UDP Server 端程式 (7/7)
28
程式宣告◦ #include <winsock2.h>
// 連結 WinSock 基本函式◦ #include <stdio.h>
// 連結 C 基本輸入輸出函式◦ #include <ws2tcpip.h>
// 連結微軟所提供的 TCP/IP 基本函式◦ #pragma comment(lib, "WS2_32.lib")
// 連結 Wsock32.lib 資料庫
UDP Client 端程式 (1/7)
29
主程式 - 宣告 void main()
{◦ char *Server = "2001:e10:1440:1:5003:317f:8e8d:dc58";
// 指定 Server IPv6 位址◦ char *Port = "5001"; // 指定 Server 的 port◦ char recvbuffer[1024]; // 接收資料的長度◦ADDRINFO Hints, *AddrInfo;
// 宣告 Hints 與 *AddrInfo 資料結構
UDP Client 端程式 (2/7)
30
主程式 - 呼叫指定的 Winsock DLL◦WORD wVersionRequested;◦wVersionRequested = MAKEWORD( 2, 2 );
// Socket 最高的版本。// 高位指定次要版本 ; 低位指定主要版本。
◦WSADATA wsaData;// 這個結構被用於存放初始化數據到 WSAStartup 。
◦WSAStartup( wVersionRequested, &wsaData );
此為微軟系統中必要呼叫 Socket 程式之固定寫法
UDP Client 端程式 (3/7)
31
主程式 -Hints◦memset(&Hints,0,sizeof(Hints));// 清除 Hints 記憶體◦Hints.ai_family = PF_INET6;// 選擇使用 IPv6◦Hints.ai_socktype=SOCK_DGRAM;// 選擇使用 UDP◦ getaddrinfo(Server,Port,&Hints,&AddrInfo);
// 取得到位址與 PORT 號並轉換 ANSI host 名稱為一個可用的位址
UDP Client 端程式 (4/7)
32
主程式 - 建立 SOCKET◦SOCKET
sockClient=socket(PF_INET6,SOCK_DGRAM,0); // 取得到伺服器位址與 port 號
UDP Client 端程式 (5/7)
33
主程式 - 迴圈 while(1){◦ char buffer[1024]=""; // 宣告 Buffer 大小為 1024 位元◦ printf("input message:"); // 顯示 input message:◦ scanf("%s",buffer);// 輸入的字串填入 buffer◦ sendto(sockClient,buffer,sizeof(buffer),0, AddrInfo-
>ai_addr, AddrInfo->ai_addrlen);// 送出 buffer 中的資料 ( 使用者輸入的 )
◦ recvfrom(sockClient,recvbuffer,50,0,NULL,NULL);// 接收 Server 回傳的資料
◦ printf("%s\n",recvbuffer);// 顯示接收到字串}
UDP Client 端程式 (6/7)
34
主程式 - 結束◦ closesocket(sockClient);
// 關閉 Client Socket◦WSACleanup();
// 清空回傳值}
UDP Client 端程式 (7/7)
35
請同學分組 ( 基本上兩人一組 ) 。 一位同學寫 UDP Client ;另一位寫 UDP Server 。 ( 自行協調 ) 展示 Client/Server 互相傳遞訊息即算完成作業。
課堂作業 02
36
網路封包分析軟體教學(Wireshark)
授課老師:陳懷恩助教:邱俊傑、江鴻毅、朱健隴國立宜蘭大學 資訊工程研究所
37
課程目標讓同學學會安裝並使用 Wireshark 抓取封包。藉此可以協助同學確認前次兩作業的成果,亦可以協助後續封包分析與除錯。
38
程式下載點: http://www.wireshark.org/download.html
Wireshark 開啟時畫面
39
選擇抓取封包網卡 (1/2) 點選紅色框來選擇抓取封包之網卡
或選實體網路卡
40
顯示電腦所有網路介面卡的列表 如何正確選擇網卡 ?
網卡名稱 IP 位址 有封包進出之網卡
選擇抓取封包網卡 (2/2)
41
點選紅色框來修改擷取封包設定 三個選項均可設定
抓取封包設定 (1/6)
42
1
2
3
選擇網卡抓取封包設定 (2/6)
43
選擇儲存文件抓取封包設定 (3/6)
44
抓取封包設定 (4/6)
45
設定停止參數 擷取數量 擷取大小 擷取時間
抓取封包設定 (5/6)
46
顯示選項
抓取封包設定 (6/6)
47
名稱解析
48
Wireshark 抓取封包畫面封包列表
封包標頭解析
印出封包 16 進位與 ASCII
抓取封包畫面 - 功能 (1/3)
49
重新選擇網卡 暫停抓取封包 重新抓取封包
暫停 重新
抓取封包畫面 - 功能 (2/3)
50
過濾擷取出來封包 ( 過濾條件如下 )◦ ip.src== 120.100.111.10 ( 擷取 120.100.111.10 來源 IP 封包 )◦ tcp/dup( 選擇擷取 Protocal)◦可以做邏輯運算 (e.g. tcp || udp)
過濾條件
抓取封包畫面 - 功能 (3/3)
51
儲存存抓取出來的封包 - 日後分析◦要先停止抓取才能做儲存動作◦ File->Save
儲存
抓取實作程式 UDP 封包
52
傳送資料
抓取實作程式 TCP 封包
53
傳送資料
安裝 Wireshark 。 利用 Client/Server 互相傳遞訊息。 展示抓取到 Client/Server 間傳遞的訊息即算完成作業。
課堂作業 03
54
Thank You !Q&A
55