Socket
DHCP, Mail, WWW, Telnet, FTP,… Socket 一組介面,介於應用程式與網路之間。 讓程式設計者不需處理網路底層的工作,而專注於本身的程式設計。 Network card Com Ethernet PPP ARP RARP IP ICMP TCP UDP Socket Library DHCP, Mail, WWW, Telnet, FTP,… Application Layer 4 / Transport Layer 3 / Network Layer 2 / Data Link Layer 1 / Physical
Winsock Windows Sockets,簡稱「Winsock」 是以 UNIX 系統上 Berkeley Sockets 的函式為基礎所發展出來的。 從winsock.dll、wsock32.dll到ws2_32.dll, 版本則由1.0、1.1至2.0版 WinSock 應用程式 ws2_32.dll (32 bit) TCP/IP Protocol Network WinSock 1.1 winsock.dll (16 bit) wsock32.dll (32 bit) Winsock 2.0
Stream Socket (TCP) Server socket() bind() Client listen() accept() WSAStartup() Server Stream Socket (TCP) socket() bind() Client listen() WSAStartup() accept() socket() Blocks until connection from client connect() Connection establishment (TCP three-way handshake) Data (request) send() recv() Data (reply) send() recv() closesocket() recv() == 0 closesocket() WSACleanup() WSAcleanup()
Stream Socket (TCP) Server socket() bind() Client listen() accept() WSAStartup() Server Stream Socket (TCP) socket() bind() Client listen() WSAStartup() accept() socket() Blocks until connection from client connect() Connection establishment (TCP three-way handshake) Data (request) send() recv() Data (reply) send() recv() closesocket() recv() == 0 closesocket() WSACleanup() WSAcleanup()
WSAStartup() 連結應用程式與 Windows Sockets DLL 的第一個函式。 int PASCAL FAR WSAStartup( WORD wVersionRequested, LPWSADATA lpWSAData ); wVersionRequested:欲使用的Windows Sockets API 的版本。 lpWSAData:指向WSADATA 資料的指標,載入動態庫。 return: 成功:0 失敗:WSASYSNOTREADY / WSAVERNOTSUPPORTED / WSAEINVAL
socket() 建立 Socket SOCKET socket( int af, int type, int protocol ); af:address format AF_INET:IPv4 AF_INET6:IPv6 type:Socket 的型態 SOCK_STREAM:TCP SOCK_DGRAM:UDP protocol:通訊協定 0:不指定 return: 成功 :Socket 的識別碼 失敗 :INVALID_SOCKET
Stream Socket (TCP) socket() bind() Server Client listen() accept() WSAStartup() Stream Socket (TCP) socket() bind() Server Client listen() WSAStartup() accept() socket() Blocks until connection from client connect() Connection establishment (TCP three-way handshake) Data (request) send() recv() Data (reply) send() recv() closesocket() recv() == 0 closesocket() WSACleanup() WSAcleanup()
bind() 指定 Socket 的 port Client 可以不用指定,作業系統會分配一個 int bind( SOCKET s, struct sockaddr_in *name, int namelen ); s:Socket 的識別碼 name:Socket 的位址 struct sockaddr_in servaddr; servaddr.sin_family = AF_INET; //IPv4 servaddr.sin_port = htons(PORT); //PORT最好大於1024 servaddr.sin_addr.s_addr = INADDR_ANY; //不指定本機IP namelen:name 的長度。 return: 成功:0 失敗:SOCKET_ERROR
listen() 設定 Socket 為監聽狀態,準備被連接。 int listen( SOCKET s, int backlog ); s:Socket 的識別碼。 backlog:佇列中連接要求的最大個數。 return: 成功:0 失敗:SOCKET_ERROR
accept() 接受連接要求,產生連接成功的 Socket 原本的 SCOKET s 還是存在的 SOCKET accept( SCOKET s, struct sockaddr_in *addr, int *addrlen ); s:Socket 的識別碼。 addr:用來存放 Client 端的資訊。 addrlen:addr 的長度。 return: 成功:新的Socket識別碼 失敗:INVALID_SOCKET
connect() 要求連接某一 TCP Socket 到指定的對方。 int connect( SOCKET s, struct sockaddr_in *name, int namelen ); s:Socket 的識別碼。 name:存放 Server 端的位址。 struct sockaddr_in clientService; clientService.sin_family = AF_INET; //IPv4 clientService.sin_port = htons(PORT); clientService.sin_addr.s_addr = inet_addr("192.168.0.100"); namelen:name的長度。 return: 成功:0 失敗:SOCKET_ERROR
Stream Socket (TCP) Server socket() bind() Client listen() accept() WSAStartup() Server Stream Socket (TCP) socket() bind() Client listen() WSAStartup() accept() socket() Blocks until connection from client connect() Connection establishment (TCP three-way handshake) Data (request) send() recv() Data (reply) send() recv() closesocket() recv() == 0 closesocket() WSACleanup() WSAcleanup()
send() 使用 Socket 傳送資料 (使用TCP) int send( SOCKET s, char *buf, int len, int flags ); s:Socket 的識別碼 buf:存放要傳送的資料的暫存區 len:buf 的長度 flags:此函式使用的模式,通常設為 0 return: 成功:送出的資料長度 失敗:SOCKET_ERROR
recv() 自 Socket 接收資料 (使用TCP) int recv( SOCKET s, char *buf, int len, int flags ); s:Socket 的識別碼 buf:存放接收到的資料的暫存區 len:buf 的長度 flags:此函式使用的函式,通常設為 0 return: 成功:接收到的資料長度 失敗:SOCKET_ERROR
Stream Socket (TCP) Server socket() bind() Client listen() accept() WSAStartup() Server Stream Socket (TCP) socket() bind() Client listen() WSAStartup() accept() socket() Blocks until connection from client connect() Connection establishment (TCP three-way handshake) Data (request) send() recv() Data (reply) send() recv() closesocket() recv() == 0 closesocket() WSACleanup() WSAcleanup()
closesocket() 關閉某一Socket int closesocket( SOCKET s ); 結束連線 (TCP) 釋放 Socket 所佔用的 port int closesocket( SOCKET s ); s:Socket 的識別碼。 return: 成功:0 失敗:SOCKET_ERROR
WSACleanup() 結束 Windows Sockets DLL 的使用。 int PASCAL FAR WSACleanup( void ); return: 成功:0 失敗:SOCKET_ERROR
Datagram Socket (UDP) 由於不必建立雙方的連線,因此只需利用 sendto 及 recvfrom 傳接資料 最後仍利用 closesocket 關閉 Socket 並釋放資源
sendto() 使用 Socket 傳送資料 int sendto( SOCKET s, char *buf, int len, int flags, struct sockaddr *to, int tolen ); s:Socket 的識別碼 buf:存放要傳送的資料的暫存區 len:buf 的長度 flags:此函式使用的模式,通常設為 0 to:存放對方的位址 tolen:to 的長度 return: 成功:送出的資料長度 失敗:SOCKET_ERROR
recvfrom() 自 Socket 接收資料 int recvfrom( SOCKET s, char *buf, int len, int flags, struct sockaddr *from, int *fromlen ); s:Socket 的識別碼 buf:存放接收到的資料的暫存區 len:buf 的長度 flags:此函式使用的模式,通常設為 0 from:用來存放對方的位址 fromlen:from 的長度 return: 成功:接收到的資料長度 失敗:SOCKET_ERROR
struct sockaddr_in Internet-specific: 位址和 port 為整數型態 short sin_family; u_short sin_port; struct in_addr sin_addr; char sin_zero[8]; }; sin_family: AF_INET sin_port: port (0-65535) sin_addr: IP 位址 sin_zero: 保留 struct in_addr { u_long s_addr; }; 位址和 port 為整數型態 u_short sin_port; //16 bit in_addr sin_addr; //32 bit
byte-ordering Internet Protocols 採用 Big-endian 不同機器間位元放的順序可能不同,傳輸時順序必需統一 host byte order 轉換 network byte order port ,16bits,用 htons() 和 ntohs() IP位址,32bits,用 htonl() 和 ntohl() 128.119.40.12 128 119 40 12 12.40.119.128 Big-Endian machine Little-Endian
Thread VC 6.0 -> Project -> setting -> C/C++ -> Project Options 修改 /MLd 成為 /MTd or /MDd,d為debug mode #include <process.h> unsigned __stdcall func(void* arg); _beginthreadex(0,0,func,(void*) arg,0,&ret);
inet_addr() 將字串型態的地址轉成二進制的無號整數 unsigned long inet_addr( char *cp ); return: 成功:無號整數的地址 失敗: INADDR_NONE
Homework 請參考你的 FINAL PROJET 說明 http://www.w3.org/Protocols/rfc2616/rfc2616.html
參考 MSDN - Windows Sockets 2 http://msdn.microsoft.com/en-us/library/ms740673(VS.85).aspx Linux Socket http://www.cs.nctu.edu.tw/~yslin/library/linuxc/main.htm Windows Sockets 電子書 http://www.sockets.com/winsock.htm Windows Socket 速查筆記 http://www.cchsu.com/art/prg_bg5/winsock.htm