Socket Win 32 API SOCKET sock sock socket

  • Slides: 35
Download presentation
Socket 使用Win 32 API

Socket 使用Win 32 API

範例 SOCKET sock; //宣告 sock = socket( //設定 AF_INET, SOCK_STREAM, IPPROTO_TCP );

範例 SOCKET sock; //宣告 sock = socket( //設定 AF_INET, SOCK_STREAM, IPPROTO_TCP );

Bind()函式 int bind( SOCKET s, const struct sockaddr* name, int namelen ); s :

Bind()函式 int bind( SOCKET s, const struct sockaddr* name, int namelen ); s : 指定好通訊協定的socket name : 指定本地端位址,資料格式為sockaddr namelen : name之資料長度(單位byte) 回傳值:-1表錯誤,否則為 0

Sockaddr_in 格式(IPv 4用) struct sockaddr_in { short sin_family; u_short sin_port; struct in_addr sin_addr; char

Sockaddr_in 格式(IPv 4用) struct sockaddr_in { short sin_family; u_short sin_port; struct in_addr sin_addr; char sin_zero[8]; }; sin_family: 位址資料族系,同樣設定為AF_INET sin_port: 主機開啟的通訊埠號 用htons() 寫入 sin_addr: 主機IP位址 in_addr資料格式 sin_zero[8]: 目前沒用處,保留以後使用

in_addr格式 typedef struct in_addr { union { struct {u_char s_b 1, s_b 2, s_b

in_addr格式 typedef struct in_addr { union { struct {u_char s_b 1, s_b 2, s_b 3, s_b 4; } S_un_b; struct {u_short s_w 1, s_w 2; } S_un_w; u_long S_addr; } S_un; } in_addr; 使用了union的結構體,實際上的大小是一個32 bit的長整數 所以只要注意u_long S_addr這個變數 將IP對此變數寫入便可 函式庫引入的標頭檔應該會有定義 #define s_addr S_un. s_addr 此後只要對前一頁之變數sin_addr. s_addr存取便可 寫入時使用inet_addr(“IP位址字串”)轉換成unsigned long

範例 SOCKET Sock; sockaddr_in sa. Server; Sock = socket( AF_INET, SOCK_STREAM, IPPROTO_TCP ); //

範例 SOCKET Sock; sockaddr_in sa. Server; Sock = socket( AF_INET, SOCK_STREAM, IPPROTO_TCP ); // 設定本機通訊用的位址 sa. Server. sin_family = AF_INET; sa. Server. sin_port = htons(5150); //啟用 5150 port sa. Server. sin_addr. s_addr = inet_addr(“ 140. 115. 65. 30”); //設定本機IP // 呼叫Bind函式 bind(Sock, (SOCKADDR*) &sa. Server, sizeof(sa. Server) );

Accept函式 接受外部連線 Blocking Non-blocking

Accept函式 接受外部連線 Blocking Non-blocking

範例 Listen. Socket 為一個bind()過且未連線的socket // 設定socket為接聽外部連線用 if (listen( Listen. Socket, 1 ) == SOCKET_ERROR)

範例 Listen. Socket 為一個bind()過且未連線的socket // 設定socket為接聽外部連線用 if (listen( Listen. Socket, 1 ) == SOCKET_ERROR) printf("Error listening on socket. n"); // 宣告一個用來和Client連線用的socket SOCKET Accept. Socket; // 接受外部連線 while(1) { Accept. Socket = SOCKET_ERROR; //尚未取得socket descriptor,等待外部連線進入時重設 while( Accept. Socket == SOCKET_ERROR ) { Accept. Socket = accept( Listen. Socket, NULL ); } printf("Client connected. n"); break; }

connect()函式 int connect( SOCKET s, const struct sockaddr* name, int namelen ); 設定方式請參照bind()函式 name內資料為

connect()函式 int connect( SOCKET s, const struct sockaddr* name, int namelen ); 設定方式請參照bind()函式 name內資料為 回傳值:-1表錯誤,否則回傳 0

範例 //Server端 int bytes. Sent; int bytes. Recv = SOCKET_ERROR; char sendbuf[32] = "Server:

範例 //Server端 int bytes. Sent; int bytes. Recv = SOCKET_ERROR; char sendbuf[32] = "Server: Sending Data. "; char recvbuf[32] = ""; bytes. Recv = recv( m_socket, recvbuf, 32, 0 ); printf( "Bytes Recv: %ldn", bytes. Recv ); bytes. Sent = send( m_socket, sendbuf, strlen(sendbuf), 0 ); printf( "Bytes Sent: %ldn", bytes. Sent ); //Client端 int bytes. Sent; int bytes. Recv = SOCKET_ERROR; char sendbuf[32] = "Client: Sending data. "; char recvbuf[32] = ""; bytes. Sent = send( m_socket, sendbuf, strlen(sendbuf), 0 ); printf( "Bytes Sent: %ldn", bytes. Sent ); while( bytes. Recv == SOCKET_ERROR ) { bytes. Recv = recv( m_socket, recvbuf, 32, 0 ); if ( bytes. Recv == 0 || bytes. Recv == WSAECONNRESET ) { printf( "Connection Closed. n"); break; } if (bytes. Recv < 0) return; printf( "Bytes Recv: %ldn", bytes. Recv ); }

closesocket() 與 shutdown()函式 int closesocket( SOCKET s ); int shutdown( SOCKET s, int how

closesocket() 與 shutdown()函式 int closesocket( SOCKET s ); int shutdown( SOCKET s, int how ); s:使用中的socket how:控制socket 作的方式 SD_RECEIVE 禁止輸入(disable recv()函式) SD_SEND 禁止輸出(disable send()函式) SD_BOTH 雙向禁止 回傳值:-1表錯誤,否則傳回 0

Server-Client Model recv() send()

Server-Client Model recv() send()

WINSOCKETS p #include <winsock 2. h>

WINSOCKETS p #include <winsock 2. h>

WINSOCKETS p p WSADATA wsadata; if (WSAStartup(0 x 101, (LPWSADATA) &wsadata) != 0) {

WINSOCKETS p p WSADATA wsadata; if (WSAStartup(0 x 101, (LPWSADATA) &wsadata) != 0) { fprintf(stderr, "echo_srv: can't use Win. Sock DLLn"); exit(1); }

WINSOCKETS p WSACleanup();

WINSOCKETS p WSACleanup();

Server端的 作流程 p 程式啟動直接開始監聽 作 WSAStartup socket bind listen p 程式結束時關閉連線 shutdown closesocket

Server端的 作流程 p 程式啟動直接開始監聽 作 WSAStartup socket bind listen p 程式結束時關閉連線 shutdown closesocket

Server停止回應的處理方法 p 1. 用非阻塞式函數 WSAAccept. Ex WSARecv Wait. For. Single. Object p 2. 多執行緒

Server停止回應的處理方法 p 1. 用非阻塞式函數 WSAAccept. Ex WSARecv Wait. For. Single. Object p 2. 多執行緒 p 3. 中斷法