1. 兩天計算機通信需要協議,通信的兩臺計算機IP必須唯一
2. 同一個計算機可以進行多個應用程序與其他計算機通信,IP地址唯一,而端口號是區別同一計算機(同一IP)的唯一標示。
3. 實際上就類似於一個辦公室的總機號碼(IP)和分機號碼(端口號)
4. 協議:爲了進行網絡中的數據交換(通信)而建立的規則、標準或約定
5. 協議=語義+語法+規則
6. 不同層具有各自不同的協議
7. 上層使用下層提供的服務,實際通信在最底層完成
8. 對等層實體之間虛擬通信|
9. TCP:面向連接的可靠的傳輸協議
10. UDP:面向無連接的不可靠的傳輸協議
11. 端口是一種抽象的軟件結構。應用程序通過系統調用與某端口建立連接後,傳輸層傳給端口的數據都被響應的進行所接收,相應進程發給傳輸層的數據都通過該端口輸出。
12. 端口用一個整數型標示符來表示。端口號跟協議相關,TCP/IP傳輸層的兩個協議TCP和UDP是完全獨立的兩個軟件模塊,因此各自的端口號也相互獨立。
13. 端口使用一個16位的數字來表示,它的範圍是0~65535,1024以下的端口號保留給預定義的服務。例如:http使用的是80端口。
14. socket(套接字):windows sockets只支持一個通信區域:網際域(AF_INET),這個域被使用網際協議簇通信的進程使用。
15. C/S模式:客戶機向服務器提出請求,服務器接收到請求後,提供相應的服務。
16. 套接字的類型
a) 流式套接字:(SOCK_STREAM):面向連接可靠的數據傳輸服務,按順序接收
b) 數據包式套接字:(SOCK_DGRAM):無連接服務。接收順序混亂。
c) 原始套接字(SOCK_RAM)
17. 基於TCP(面向連接)的socket編程
a) 服務器端程序:
i. 創建套接字socket
ii. 將套接字綁定到一個本地地址和端口上bind
iii. 將套接字設爲監聽模式,準備接收客戶請求listen
iv. 等待客戶請求到了;當請求到來後,接收連接請求,返回一個新的對應於此次連接的套接字accept
v. 用返回的套接字和客戶端進行通信rend/recv
vi. 返回,等待另一客戶請求
vii. 關閉套接字
b) 客戶端程序:
i. 創建套接字socket
ii. 向服務端發出連接請求connect
iii. 和服務器端進行通信rend/recv
iv. 關閉套接字
18. 基於UDP的socket編程
a) 服務器端(接收端)程序:
i. 創建套接字socket
ii. 將套接字綁定到一個本地地址和端口上bind
iii. 等待接收數據recv/from
iv. 關閉套接字
b) 客戶端(發送端)程序:
i. 創建套接字socket
ii. 向服務器發送數據sendto
iii. 關閉套接字
19.
int WSAStartup (
WORD wVersionRequested, //打算使用的最高winsock版本號
LPWSADATA lpWSAData //是個結構體,接收socket的詳細信息
);
20.
alt+F8
:格式化代碼
21.
面向
TCP
的連接,服務器端
a)
套接字
SOCKET socket (
int af, //指定地址簇
int type, //socket類型
int protocol //協議
);
b)
綁定
int bind (
SOCKET s, //要綁定的套接字
const struct sockaddr FAR* name, //指定了該套接字的本地地址信息
int namelen //該地址結構的長度
);
struct sockaddr {
u_short sa_family;
char sa_data[14];
};
c) 監聽
int listen (
SOCKET s,
int backlog
);
d) 接受連接
SOCKET accept (
SOCKET s,
struct sockaddr FAR* addr,
int FAR* addrlen
);
e)
發送
int send (
SOCKET s, //建立連接的socket
const char FAR * buf, //發送的數據
int len, //發送數據的長度
int flags
);
f)
接收
int recv (
SOCKET s,
char FAR* buf,
int len,
int flags
);
g) 需要的文件
#include <winsock2.h>
需要連接一個動態鏈接庫:ws2_32.lib
22. 服務器端:
a) Socket
b) 連接:connect
int connect (
SOCKET s,
const struct sockaddr FAR* name,
int namelen
);
c) 接收:recv
d) 發送:send
e) 關閉:closesocket
23. Tcp服務端程序:
- #include <WINSOCK2.H>
- #include <stdio.h>
- void main()
- {
- WORD wVersionRequested;
- WSADATA wsaData;
- int err;
- wVersionRequested = MAKEWORD( 1, 1 );
- err = WSAStartup( wVersionRequested, &wsaData );
- if ( err != 0 ) {
- return;
- }
- if ( LOBYTE( wsaData.wVersion ) != 1 ||
- HIBYTE( wsaData.wVersion ) != 1 ) {
- WSACleanup( );
- return;
- }
- SOCKET sockSrv=socket(AF_INET,SOCK_STREAM,0);
- SOCKADDR_IN addrSrv;
- addrSrv.sin_addr.S_un.S_addr=htonl(INADDR_ANY);
- addrSrv.sin_family=AF_INET;
- addrSrv.sin_port=htons(6000);
- bind(sockSrv,(SOCKADDR*)&addrSrv,sizeof(SOCKADDR));
- listen(sockSrv,5);
- SOCKADDR_IN addrClient;
- int len=sizeof(SOCKADDR);
- while(1)
- {
- SOCKET sockConn=accept(sockSrv,(SOCKADDR*)&addrClient,&len);
- char sendBuf[100];
- sprintf(sendBuf,"Welcome %s to 劉窪村",inet_ntoa(addrClient.sin_addr));
- send(sockConn,sendBuf,strlen(sendBuf)+1,0);
- char recvBuf[100];
- recv(sockConn,recvBuf,100,0);
- printf("%s\n",recvBuf);
- closesocket(sockConn);
- }
- }
24. Tcp客戶端程序:
- #include <WINSOCK2.H>
- #include <stdio.h>
- void main()
- {
- WORD wVersionRequested;
- WSADATA wsaData;
- int err;
- wVersionRequested = MAKEWORD( 1, 1 );
- err = WSAStartup( wVersionRequested, &wsaData );
- if ( err != 0 ) {
- return;
- }
- if ( LOBYTE( wsaData.wVersion ) != 1 ||
- HIBYTE( wsaData.wVersion ) != 1 ) {
- WSACleanup( );
- return;
- }
- SOCKET sockClient=socket(AF_INET,SOCK_STREAM,0);
- SOCKADDR_IN addrSrv;
- addrSrv.sin_addr.S_un.S_addr=inet_addr("127.0.0.1");//服務器端的地址
- addrSrv.sin_family=AF_INET;
- addrSrv.sin_port=htons(6000);
- connect(sockClient,(SOCKADDR*)&addrSrv,sizeof(SOCKADDR));
- char recvBuf[100];
- recv(sockClient,recvBuf,100,0);
- printf("%s\n",recvBuf);
- send(sockClient,"This is 劉窪村",strlen("This is 劉窪村")+1,0);
- closesocket(sockClient);
- WSACleanup();
- }
25. 運行之後,開啓了6個客戶端,一個服務器端。程序運行效果:
26. 面向UDP的連接
27. 服務器:socket
a) bind
b) 接收數據:
int recvfrom (
SOCKET s, //套接字
char FAR* buf, //接收數據
int len, //長度
int flags, //會影響調用行爲,0
struct sockaddr FAR* from, //接收發送方的地址信息
int FAR* fromlen //接收長度
);
c) 關閉closesocket
d) Cleanup
28. UDP服務器端程序:
- #include <WINSOCK2.H>
- #include <stdio.h>
- void main()
- {
- WORD wVersionRequested;
- WSADATA wsaData;
- int err;
- wVersionRequested = MAKEWORD( 1, 1 );
- err = WSAStartup( wVersionRequested, &wsaData );
- if ( err != 0 ) {
- return;
- }
- if ( LOBYTE( wsaData.wVersion ) != 1 ||
- HIBYTE( wsaData.wVersion ) != 1 ) {
- WSACleanup( );
- return;
- }
- SOCKET sockSrv=socket(AF_INET,SOCK_DGRAM,0);
- SOCKADDR_IN addrSrv;
- addrSrv.sin_addr.S_un.S_addr=htonl(INADDR_ANY);
- addrSrv.sin_family=AF_INET;
- addrSrv.sin_port=htons(6000);
- bind(sockSrv,(SOCKADDR*)&addrSrv,sizeof(SOCKADDR));
- SOCKADDR_IN addrClient;
- int len=sizeof(SOCKADDR);
- char recvBuf[100];
- recvfrom(sockSrv,recvBuf,100,0,(SOCKADDR*)&addrClient,&len);
- printf("%s\n",recvBuf);
- closesocket(sockSrv);
- WSACleanup();
- }
28. UDP客戶端:
a) socket定義
b) 發送:
int sendto (
SOCKET s,
const char FAR * buf,
int len,
int flags,
const struct sockaddr FAR * to,
int tolen
);
29. UDP客戶端程序
- #include <WINSOCK2.H>
- #include <stdio.h>
- void main()
- {
- WORD wVersionRequested;
- WSADATA wsaData;
- int err;
- wVersionRequested = MAKEWORD( 1, 1 );
- err = WSAStartup( wVersionRequested, &wsaData );
- if ( err != 0 ) {
- return;
- }
- if ( LOBYTE( wsaData.wVersion ) != 1 ||
- HIBYTE( wsaData.wVersion ) != 1 ) {
- WSACleanup( );
- return;
- }
- SOCKET sockClient=socket(AF_INET,SOCK_DGRAM,0);
- SOCKADDR_IN addrSrv;
- addrSrv.sin_addr.S_un.S_addr=inet_addr("127.0.0.1");
- addrSrv.sin_family=AF_INET;
- addrSrv.sin_port=htons(6000);
- sendto(sockClient,"Hello 劉窪村",strlen("Hello 劉窪村")+1,0,
- (SOCKADDR*)&addrSrv,sizeof(SOCKADDR));
- closesocket(sockClient);
- WSACleanup();
- }
30. 注意:每個程序都要加上ws2_32.lib鏈接庫。如下添加: