【网络编程】之二、socket API学习
套接字API函數(shù):
1、socket函數(shù):The?socket?function creates a socket that is bound to a specific transport service provider.
2、bind函數(shù):The?bind?function associates a local address with a socket.(一般用于服務(wù)器)
3、listen函數(shù):The?listen?function places a socket in a state in which it is listening for an incoming connection.(一般用于服務(wù)器)
4、connect函數(shù):The?connect?function establishes a connection to a specified socket.(用戶客戶端)
5、accept函數(shù):The?accept?function permits an incoming connection attempt on a socket.(用于服務(wù)器)
6、send和recv,sendto和recvfrom函數(shù):send and recv data!
下面我們就來挨個講解:
socket:
函數(shù)原型是:
[cpp]?view plaincopy
第一個參數(shù)af指的是給創(chuàng)建的套接字制定一個地址族!這些值已經(jīng)在windows頭文件中給你定義好了!一般形式是AF_或者PF_!MSDN中有一句話是Note that the values for the AF_ address family and PF_ protocol family constants are identical (for example,?AF_INETand?PF_INET), so either constant can be used.
AF_INET:表示IPV4網(wǎng)絡(luò)協(xié)議;
AF_INET6:表示IPV6網(wǎng)絡(luò)協(xié)議;
?AF_UNIX:表示本地套接字(使用一個文件)
第二個參數(shù)type指的是要創(chuàng)建的套接字的類型,他的值也是在頭文件中一定定義好的!
SOCK_STREAM: ? TCP進行傳輸
SOCK_DGRAM: ? UDP進行傳輸
SOCK_RAW: ?在網(wǎng)絡(luò)層上的原始套接字,這個socket類型使用ICMP公共協(xié)議
SOCK_SEQPACKET: ? 可靠地連續(xù)數(shù)據(jù)包服務(wù)
最后一個參數(shù)protocol指定的是實際使用的傳輸協(xié)議!他的值也是定義在?Winsock2.h?and?Wsrm.h?header files.。 如果在這里設(shè)為0的話,那么我們就是使用前兩個參數(shù)指定的缺省協(xié)議!
如果函數(shù)失敗,就返回INVALID_SOCKET。也就是-1,否則,函數(shù)會返回一個代表新分配的描述符的整數(shù)。
bind函數(shù):
函數(shù)原型是:
[cpp]?view plaincopy
第一個參數(shù)s是一個socket的描述符,你要把你生成的套接字傳進來!注意,這個socket是未綁定的。
第二個參數(shù)是一指向sockaddr類型的指針。
有兩個簡單的結(jié)構(gòu):
[cpp]?view plaincopy
下面說一下sin_addr: ?sin_addr結(jié)構(gòu)體中只有一個唯一的字段s_addr,表示IP地址,該字段是一個整數(shù),一般用函數(shù)inet_addr()把字符串形式的IP地址轉(zhuǎn)換成unsigned?long型的整數(shù)值后再置給s_addr。 ?我們也可以把htonl(INADDR_ANY)置給s_addr,這樣做的好處是不論哪個網(wǎng)段上的客戶程序都能與該服務(wù)程序通信;
用0來填充sin_zero數(shù)組,目的是讓sockaddr_in結(jié)構(gòu)的大小與sockaddr結(jié)構(gòu)的大小一致。
上面還有最后一個參數(shù)namelen沒有說,相信應(yīng)該知道了,這是用來指定socketaddr的長度的。
[cpp]?view plaincopy
listen函數(shù):
函數(shù)原型是:
[cpp]?view plaincopy
函數(shù)調(diào)用成功返回0,如果失敗就返回SOCKET_ERROR;
connect函數(shù):
函數(shù)原型是:
[cpp]?view plaincopy
函數(shù)成功返回0,失敗則返回-1 (SOCKET_ERROR);
[cpp]?view plaincopyaccept函數(shù):
函數(shù)原型是:
[cpp]?view plaincopy
函數(shù)調(diào)用成功就返回套接字描述符,否則失敗就返回INVALID_SOCKET ?-1;
s:監(jiān)聽的套接字描述符;
addr:指向sockaddr結(jié)構(gòu)的指針。客戶機地址信息。
addrlen:確定客戶機結(jié)構(gòu)的大小;
[cpp]?view plaincopy
函數(shù)原型是:
[cpp]?view plaincopy
客戶程序一般用send函數(shù)向服務(wù)器發(fā)送請求,而服務(wù)器則通常用send函數(shù)來向客戶程序發(fā)送應(yīng)答;
s:指定發(fā)送端套接字描述符;
buf:一個存放著應(yīng)用程序要發(fā)送數(shù)據(jù)的緩沖區(qū);
len:實際要發(fā)送的數(shù)據(jù)的字節(jié)數(shù);
flags:標志位,影響函數(shù)行為,一般置為0;
注意:每一個除send外的Socket函數(shù)在執(zhí)行的最開始總要先等待套接字的發(fā)送緩沖中的數(shù)據(jù)被協(xié)議傳送完畢才能繼續(xù),如果在等待時出現(xiàn)網(wǎng)絡(luò)錯誤,那么該Socket函數(shù)就返回 SOCKET_ERROR
[cpp]?view plaincopy
s:指定接收端套接字描述符;
buf:指明一個緩沖區(qū),該緩沖區(qū)用來存放recv函數(shù)接收到的數(shù)據(jù);
len:指明buf的長度;
flags:標志位,影響函數(shù)的行為,一般為0;
如果recv函數(shù)出錯就會返回SOCKET_ERROR,如果recv函數(shù)在等待協(xié)議接受數(shù)據(jù)時網(wǎng)絡(luò)中斷了,就會返回0;
send分為阻塞和非阻塞:
阻塞模式下,如果正常的話,會直到把你所需要發(fā)送的數(shù)據(jù)發(fā)完再返回;
非阻塞模式下,會根據(jù)你的socket在底層的可用緩沖區(qū)的大小來將你的緩沖區(qū)當中的數(shù)據(jù)拷貝過去,有多大的緩沖區(qū)就拷貝多少。緩沖區(qū)滿了就立即返回。這個時候的返回值只表示拷貝到緩沖區(qū)多少數(shù)據(jù),但是并不代表發(fā)送多少數(shù)據(jù)。同時剩下的部分需要你再次調(diào)用send才會再一次拷貝到底層緩沖區(qū);
2012/8/15
jofranks 于南昌
總結(jié)
以上是生活随笔為你收集整理的【网络编程】之二、socket API学习的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 【网络编程】之一、初识WinSocket
- 下一篇: 【网络编程】之三、socket网络编程