TCP Server端程式

Download Report

Transcript TCP Server端程式

授課老師:陳懷恩
助教:邱俊傑、江鴻毅、朱健隴
國立宜蘭大學 資訊工程研究所
1
教同學們使用Microsoft Visual Studio 2008
以 及 C 語 言 寫 出 IPv6 TCP 的 Server 端 與
Client 端 程式
2
TCP Server
Socket()
1. 建立Socket(使用
Socket()函數)
Bind()
2. 連結Socket(使用
bind()函數)
Listen()
3. 開啟listening socket
TCP Client
1. 建立Socket(使用
Socket()函數)
Socket()
Accept()
連線要求
TCP three-way handshake
4. 等待接受Client 端連線
要求
2. 使用Connect()函
數連線要求
Connect()
3. Send()函數送出
資料給Server
Send()
資料
recv()
5.使用recv()接收資料
4. 使用recv()接收
資料
recv()
資料
Send()
6. send()函數送出
關閉Socket(使用close()函數)
3

程式宣告
◦ #include <winsock2.h>
//連結WinSock基本函式
◦ #include <stdio.h>
//連結C基本輸入輸出函式
◦ #include <ws2tcpip.h>
//連結微軟所提供的TCP/IP基本函式
◦ #pragma comment(lib, "WS2_32.lib")
//連結Wsock32.lib資料庫
4


主程式-宣告
void main()
這個部分請同學填寫伺服器的IPv6位址
{
◦
◦
◦
◦
◦
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
5

主程式-呼叫指定的Winsock DLL
◦ WORD wVersionRequested;
◦ wVersionRequested = MAKEWORD( 2, 2 );
// Socket最高的版本。
// 高位指定次要版本; 低位指定主要版本。
◦ WSADATA wsaData;
//這個結構被用於存放初始化數據到WSAStartup 。
◦ WSAStartup( wVersionRequested, &wsaData );

此為微軟系統中必要呼叫Socket程式之固定寫法
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
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長度
printf()是輸出輸入函式庫中的函式
8


主程式-迴圈
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
}
9

主程式-結束
◦ closesocket(msgsock);
結束先前建立的socket
//關閉Client Socket
◦ WSACleanup();
//清空回傳值
可與WSAStartup()函式相呼應(第6頁)
}
10

程式宣告
◦ #include <winsock2.h>
//連結WinSock基本函式
◦ #include <stdio.h>
//連結C基本輸入輸出函式
◦ #include <ws2tcpip.h>
//連結微軟提供的TCP/IP基本函式
◦ #pragma comment(lib, "WS2_32.lib")
//連結Wsock32.lib資料庫
同學注意到了嗎?這個部分與Server端程式相同。
11


主程式-宣告
void main()
這個部分請同學填寫你要連線的電腦
IPv6位址
{
◦ 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資料結構
12

主程式-呼叫指定的Winsock DLL
◦ WORD wVersionRequested;
◦ wVersionRequested = MAKEWORD( 2, 2 );
// Socket最高的版本。
// 高位指定次要版本; 低位指定主要版本。
◦ WSADATA wsaData;
//這個結構被用於存放初始化數據到WSAStartup 。
◦ WSAStartup( wVersionRequested, &wsaData );

此為微軟系統中必要呼叫Socket程式之固定寫法
這個部分與Server端程式相同
13

主程式-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名稱為一個可用的
位址
這個部分與Server端程式相同
14

主程式-建立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]="";
//宣告發送資料的長度
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);
//顯示接收到字串
}
16

主程式-結束
◦ closesocket(sockClient);
//關閉Client Socket
◦ WSACleanup();
//清空回傳值
}
結束Socket,這個部分與Server端程式相同。
17





助教將於課堂上公布 Server IP位址
Server Port為 5001
請同學寫出 IPv6 TCP Client端 程式
輸入學號發送到Server端
助教確認正確收到即算完成作業
18
授課老師:陳懷恩
助教:邱俊傑、江鴻毅、朱健隴
國立宜蘭大學 資訊工程研究所
19
教同學們使用Microsoft Visual Studio 2008
以 及 C 語 言 寫 出 IPv6 UDP 的 Server 端 與
Client 端程式
20
UDP Server
UDP Client
1. 建立Socket(使用Socket
函數)
Socket()
1. 建立Socket(使用
Socket函數)
Bind()
2. 連結Socket(使用
bind函數)
Recvfrom()
Socket()
3. 以recvfrom()函數接
收Client端傳來的資
料
等待資料接收
2. 以Sendto()函數傳送資料
給Server端
3. 以recvfrom()函數接收
Server端傳來的資料
Sendto()
Recvfrom()
4. 關閉Socket(使用Close
()函數)
Close()
送出資料
回覆資料
Sendto()
4.以Sendto()函數傳送資
料給Client端
5.關閉Socket(使用Close
()函數)
21

程式宣告
◦ #include <winsock2.h>
//連結WinSock基本函式
◦ #include <stdio.h>
//連結C基本輸入輸出函式
◦ #include <ws2tcpip.h>
//連結微軟所提供的TCP/IP基本函式
◦ #pragma comment(lib, "WS2_32.lib")
//連結Wsock32.lib資料庫
22


主程式-宣告
void main()
這個部分請同學填寫伺服器的IPv6位址
{
◦
◦
◦
◦
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的結構
23

主程式-呼叫指定的Winsock DLL
◦ WORD wVersionRequested;
◦ wVersionRequested = MAKEWORD( 2, 2 );
// Socket最高的版本。
// 高位指定次要版本; 低位指定主要版本。
◦ WSADATA wsaData;
//這個結構被用於存放初始化數據到WSAStartup 。
◦ WSAStartup( wVersionRequested, &wsaData );

此為微軟系統中必要呼叫Socket程式之固定寫法
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名稱為一個可用
的位址
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長度
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);
//顯示傳送到字串
}
27

主程式-結束
◦ closesocket(sockSrv);
//關閉Client Socket
◦ WSACleanup();
//清空回傳值
}
28

程式宣告
◦ #include <winsock2.h>
//連結WinSock基本函式
◦ #include <stdio.h>
//連結C基本輸入輸出函式
◦ #include <ws2tcpip.h>
//連結微軟所提供的TCP/IP基本函式
◦ #pragma comment(lib, "WS2_32.lib")
//連結Wsock32.lib資料庫
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資料結構
30

主程式-呼叫指定的Winsock DLL
◦ WORD wVersionRequested;
◦ wVersionRequested = MAKEWORD( 2, 2 );
// Socket最高的版本。
// 高位指定次要版本; 低位指定主要版本。
◦ WSADATA wsaData;
//這個結構被用於存放初始化數據到WSAStartup 。
◦ WSAStartup( wVersionRequested, &wsaData );

此為微軟系統中必要呼叫Socket程式之固定寫法
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名稱為一個可
用的位址
32

主程式-建立SOCKET
◦ SOCKET
sockClient=socket(PF_INET6,SOCK_DGRAM,0);
//取得到伺服器位址與port號
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);//顯示接收到字串
}
34

主程式-結束
◦ closesocket(sockClient);
//關閉Client Socket
◦ WSACleanup();
//清空回傳值
}
35



請同學分組(基本上兩人一組)。
一位同學寫UDP Client;另一位寫UDP Server。(自行協調)
展示Client/Server互相傳遞訊息即算完成作業。
36
授課老師:陳懷恩
助教:邱俊傑、江鴻毅、朱健隴
國立宜蘭大學 資訊工程研究所
37
讓同學學會安裝並使用Wireshark抓取封包。藉此
可以協助同學確認前次兩作業的成果,亦可以協
助後續封包分析與除錯。
38

程式下載點:
http://www.wireshark.org/download.html
39

點選紅色框來選
擇抓取封包之網
卡
或選實體網路卡
40


顯示電腦所有網路介面卡的列表
如何正確選擇網卡?



網卡名稱
IP位址
有封包進出之網卡
41


1
點選紅色框來修改擷取
封包設定
三個選項均可設定
2
3
42

選擇網卡
43

選擇儲存文件
44

設定停止參數



擷取數量
擷取大小
擷取時間
45

顯示選項
46

名稱解析
47
Wireshark抓取封包畫面
封包列表
封包標頭解析
印出封包16進位
與ASCII
48



重新選擇網卡
暫停抓取封包
重新抓取封包
暫停 重新
49

過濾擷取出來封包(過濾條件如下)
◦ ip.src== 120.100.111.10 (擷取120.100.111.10來源IP封包)
◦ tcp/dup(選擇擷取Protocal)
◦ 可以做邏輯運算(e.g. tcp || udp)
過濾條件
50

儲存存抓取出來的封包-日後分析
◦ 要先停止抓取才能做
儲存動作
◦ File->Save
儲存
51
傳送資料
52
傳送資料
53



安裝Wireshark。
利用Client/Server互相傳遞訊息。
展示抓取到Client/Server間傳遞的訊息即算完成作業。
54
55