程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> .NET網頁編程 >> C# >> 關於C# >> socket編程學習筆記(1), Unix Socket和Windows Socket

socket編程學習筆記(1), Unix Socket和Windows Socket

編輯:關於C#

1,關於Unix Socket

1.1 什麼是Socket?

Socket是網絡文件描述符。在基於Socket的編程技術中,用戶不直接訪問發送和接收包的網絡接口設備,而是建立一個中間文件描述符來處理編程接口到網絡的操作。

1.2 Socket包括哪些內容?

一個特殊的通信域,比如一個網絡連接

一個特殊的通信類型,比如流或者數據報

一個特殊的協議,比如TCP或者UDP

1.3 Unix的Socket() C函數詳細說明:

int socket(int domain, int type, int protocol)

domain的取值:

PF_UNIX Unix IPC通信

PF_INET IPV4通信

PF_INET6IPV6

PF_IPX Novell IPX

PF_NETLINKKernel用戶接口驅動程序

PF_X25 X.25

PF_AX25

PF_ATMPVCATM PVC

PF_APPLETALKAppleTalk協議

PF_PACKET低級包接口

type的取值:

SOCK_STREAM使用面向連接的通信包

SOCK_DGRAM使用無連接的通信包

SOCK_SEQPACKET使用有固定最大長度的面向連接的通信包

SOCK_RAW使用原IP包

SOCK_RDM使用不保證次序的可靠數據報

Protocol:

一般使用與type對應的默認協議,用0表示。

例如: int newsocket = socket(PF_INET, SOCK_STREAM, 0 );//使用TCP

1.4 使用面向連接的套接字

IP領域只有兩種類型: connection-oriented, connectionless

使用面向連接的套接字,服務器和客戶端需要如下通信方式:

Server  Client

socket()socket()
bind()
listen()
accept() <----connect()
recv()  <----send()
send()  ---->recv()
close() <--->close()

1.5 使用無連接的套接字

SOCK_DGRAM使用UDP協議。通信方式如下:

UDP ServerUDP Client

socket()socket()
bind()
recvform() <---sendto()
sendto()  --->recvform()
close() close()

1.6 使用無阻塞的I/O方法

什麼是阻塞?

比如使用recv(),如果函數接受不到數據,就會阻塞程序的繼續執行。

如何防止阻塞?

使用fcntl()函數,把套接字設置為無阻塞模式。

int newsocket;
newsocket = socket(PF_INET, SOCK_STREAM, 0 );
fcntl( newsocket, F_SETEL, O_NONBLOCK );

以後使用recv()就不會阻塞了。

另一種方式是使用多路套接字select()

2 WinSock技術

總的說來,就是模仿Unix socket的實現。

2.1 WinSock下的函數和流程

Server Client
WSAstartup()WSAStartup()
WSASocket()WASSocket()
bind()
listen()
WSAAccept() <--WSAConnect()
WSARecv()  <--WSASend()
WSASend()  -->WSARecv()
close()   <->close()
WSACleanup()WSACleanup()

與Unix socket的最主要區別就是在最上面加了WSAStartup()函數,最後加了WSACleanup()函數。中間都是一樣的。

int WSAStartup(WORD wversion, LPWSADATA lpWSAData)

第一個參數是版本,要求2.2 還是1.1.

函數成功以後,lpWSAData指向一個結構體,包括win sock的一些信息。

WSACleanup()函數用來釋放winsocket庫,這個函數之後,再調用任何socket函數,都會出錯。

2.2 WinSock

2.2.1 采用類似Unix的方法

使用ioctlsocket()把socket設置為無堵塞的。

使用select()多路傳輸多個套接字。

2.2.2 使用WSAAsyncSelect()函數

WSAAsynSelect()擴展了Unix的select()函數,它允許Windows進行查詢套接字的操作。創建的WSAAsynSelect()方法包括要監視的套接字和一個Windows消息值,當某個套接字出現的時候,該消息就會送到窗口。

int WSAAsynSelect(Socket s, HWND hwnd, unsigned int wMsg, long lEvent)

Event包括如下事件類型:

FD_ACCEPT 用套接字建立一個新的連接

FD_ADDRESS_LIST_CHANGE為套接字的協議族而改變的本地地址列表

FD_CLOSE 一個現有的連接被關閉

FD_CONNECT 已經完成與遠程主機連接的套接字

FD_GROUP_QOS 套接字組的QOS已經改變

FD_OOB 套接字受到帶外的數據

FD_QOS 套接字的QOS已經改變

FD_READ 套接字有准備讀的數據

FD_ROUTING_INTERFACE_CHANGE套接字的路由接口已經改變到一個特殊的目的地

FD_WRITE 套接字准備寫數據

Example:

WSAAsynSelect( sock, hwnd, WM_SOCKET, FD_READ | FD_CLOSE );

2.2.3 使用WSAEventSelect()函數

為了適應一些應用程序例如精靈程序或者某些沒有用戶界面的服務程序(因此不使用窗口句柄),Windows Socket 2提供了WSAEventSelect()函數和WSAEnumNetworkEvents()函數。WSAEventSelect()函數和WSAAyncSelect()函數很類似,區別僅在於當一個FD_XXX網絡事件發生時,WSAEventSelect()函數將導致一個應用程序指定的事件對象被設置,而WSAAyncSelect()將導致一條Windows消息被發送(例如FD_READ,FD_WRITE等等)。

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved