linux网络编程--数据结构与函数原型
套接字有三種類型:流式套接字(SOCK_STREAM),數據報套接字(SOCK_DGRAM)及原始套接字。
socket()
?? |
?bind()
?? |???????????????????????
listen()???????????????
?? |????????????????? ?socket()
accept()??????????????? |
?? |??????????????? ?connect()
?? |?????????????????????? ?|
read()????????????? write()
?? |????????????????????? ?|
write()????????????? read()
?? |????????????????????? ?|
close()????????????close()
socket()
?? |
?bind()
?? |???????????????????? ?socket()?????
?? |??????????????????????????|
?? |??????????????????? ? ?bind()
recvfrom()????????????? |
?? |???? <---------?? sendto()
?? |?????????????????????? ? |
sendto() -----> recvfrom()
?? |???????????????????????? |
close()?????????????? close()
??????????
struct sockaddr {
??? unsigned short sa_family; /* address族, AF_xxx */
??? char sa_data[14]; /* 14 bytes的協議地址 */
};
sa_family 一般來說,都是“AFINET”。
sa_data 包含了一些遠程電腦的地址、端口和套接字的數目,它里面的數據是雜溶在一切的。為了處理struct sockaddr, 程序員建立了另外一個相似的結構 struct sockaddr_in:
struct sockaddr_in (“in” 代表 “Internet”)
struct sockaddr_in {
??? short int sin_family; /* Internet地址族 */
??? unsigned short int sin_port; /* 端口號 */
??? struct in_addr sin_addr; /* Internet地址 */
??? unsigned char sin_zero[8]; /* 添0(和struct sockaddr一樣大小)*/
};
??? 這個結構提供了方便的手段來訪問socket address(struct sockaddr)結構中的每一個元素。注意sin_zero[8] 是為了是兩個結構在內存中具有相同的尺寸,使用sockaddr_in 的時候要把sin_zero 全部設成零值(使用bzero()或memset()函數)。而且,有一點很重要,就是一個指向struct sockaddr_in 的指針可以聲明指向一個sturct sockaddr 的結構。所以雖然socket() 函數需要一個structaddr * ,你也可以給他一個sockaddr_in * 。注意在structsockaddr_in 中,sin_family 相當于在 struct sockaddr 中的sa_family,需要設成“AF_INET”。
最后一定要保證sin_port 和sin_addr 必須是網絡字節順序。
/* 因特網地址 (a structure for historical reasons) */
struct in_addr {
??? unsigned long s_addr;
};
??? 如果你聲明了一個“ ina ” 作為一個struct sockaddr_in 的結構, 那么“ina.sin_addr.s_addr”就是4 個字節的IP 地址(按網絡字節順序排放)。需要注意的是,即使你的系統仍然使用聯合而不是結構來表示struct in_addr,你仍然可以用上面的方法得到4 個字節的IP 地址。
??? 在struct sockaddr_in 中的sin_addr和sin_port他們的字節順序都是網絡字節順序,而sin_family卻不是網絡字節順序的。
???
??? ina.sin_addr.s_addr = inet_addr(“166.111.69.52”);
??? inet_addr() 返回的地址已經是網絡字節順序了,你沒有必要再去調用htonl() 函數。
??? printf(“%s”, inet_ntoa(ina.sin_addr));
???
#include <sys/types.h>
#include <sys/socket.h>
int socket(int domain , int type , int protocol);
AF_INET
SOCK_STREAM、SOCK_DGRAM
0
錯誤返回-1,全局變量errno被設置為錯誤碼。
#include <sys/types.h>
#include <sys/socket.h>
int bind (int sockfd , struct sockaddr *my_addr , int addrlen) ;
sockfd 是由socket()函數返回的套接字描述符。
my_addr 是一個指向struct sockaddr 的指針,包含有關你的地址的信息:名稱、端口和IP 地址。
addrlen 可以設置為sizeof(struct sockaddr)。
#include <sys/types.h>
#include <sys/socket.h>
int connect (int sockfd, struct sockaddr *serv_addr, int addrlen);
sockfd :套接字文件描述符,由socket()函數返回的。
serv_addr 是一個存儲遠程計算機的IP 地址和端口信息的結構。
addrlen 應該是sizeof(struct sockaddr)。
#include <sys/socket.h>
int listen(int sockfd, int backlog);
sockfd 是一個套接字描述符,由socket()系統調用獲得。
backlog 是未經過處理的連接請求隊列可以容納的最大數目。
#include <sys/socket.h>
int accept(int sockfd, void *addr, int *addrlen);
sockfd 是正在listen() 的一個套接字描述符。
addr 一般是一個指向struct sockaddr_in 結構的指針;里面存儲著遠程連接過來的計算機的信息(比如遠程計算機的IP 地址和端口)。
addrlen 是一個本地的整型數值,在它的地址傳給accept() 前它的值應該是sizeof(struct sockaddr_in);accept()不會在addr 中存儲多余addrlen bytes 大小的數據。如果accept()函數在addr 中存儲的數據量不足addrlen,則accept()函數會改變addrlen 的值來反應這個情況。
#include <sys/types.h>
#include <sys/socket.h>
int send(int sockfd, const void *msg, int len, int flags);
sockfd 是代表你與遠程程序連接的套接字描述符。
msg 是一個指針,指向你想發送的信息的地址。
len 是你想發送信息的長度。
flags 發送標記。一般都設為0(你可以查看send 的man pages來獲得其他的參數值并且明白各個參數所代表的含義)。
#include <sys/types.h>
#include <sys/socket.h>
int recv(int sockfd, void *buf, int len, unsigned int flags);
sockfd 是你要讀取數據的套接字描述符。
buf 是一個指針,指向你能存儲數據的內存緩存區域。
len 是緩存區的最大尺寸。
flags 是recv() 函數的一個標志,一般都為0 (具體的其他數值和含義請參考recv()的man pages)。
#include <sys/types.h>
#include <sys/socket.h>
int sendto(int sockfd, const void *msg, int len, unsigned int flags,const struct sockaddr *to, int tolen);
sockfd 是代表你與遠程程序連接的套接字描述符。
msg 是一個指針,指向你想發送的信息的地址。
len 是你想發送信息的長度。
flags 發送標記。一般都設為0。(你可以查看send 的man pages 來獲得其他的參數值并且明白各個參數所代表的含義)
to 是一個指向struct sockaddr 結構的指針,里面包含了遠程主機的IP 地址和端口數據。
tolen 只是指出了struct sockaddr 在內存中的大小sizeof(struct sockaddr)。
#include <sys/types.h>
#include <sys/socket.h>
int recvfrom(int sockfd, void *buf, int len, unsigned int flags,struct sockaddr *from, int *fromlen);
sockfd 是你要讀取數據的套接字描述符。
buf 是一個指針,指向你能存儲數據的內存緩存區域。
len 是緩存區的最大尺寸。
flags 是recv() 函數的一個標志,一般都為0 (具體的其他數值和含義請參考recv()的man pages)。
from 是一個本地指針,指向一個struct sockaddr 的結構(里面存有源IP 地址和端口數).
fromlen 是一個指向一個int 型數據的指針,它的大小應該是sizeof ( struct sockaddr).當函數返回的時候,formlen 指向的數據是form 指向的struct sockaddr 的實際大小.
#include <sys/socket.h>
int shutdown(int sockfd, int how);
sockfd 是一個你所想關閉的套接字描述符.
how 可以取下面的值。0 表示不允許以后數據的接收操;1 表示不允許以后數據的發送操作;2 表示和close()一樣,不允許以后的任何操作(包括接收,發送數據)
shutdown() 如果執行成功將返回0,如果在調用過程中發生了錯誤,它將返回–1,全局變量errno 中存儲了錯誤代碼.
?
?
#include<sys/types.h>
#include<sys/socket.h>
int getsockopt(int sockfd, int level, int name, char *value, int *optlen);
int setsockopt(int sockfd, int level, int name, char *value, int *optlen);
sockfd 必須是一個已打開的套接字。
level 是函數所使用的協議標準(protocol level)(TCP/IP 協議使用IPPROTO_TCP,套接字標準的選項實用SOL_SOCKET)。
name 選項在套接字說明書中(man page)有詳細說明。
value 指向為getsockopt()函數所獲取的值,setsockopt()函數所設置的值的地址。
optlen 指針指向一個整數,該整數包含參數以字節計算的長度。
#include <sys/socket.h>
int getpeername(int sockfd, struct sockaddr *addr, int *addrlen);
sockfd 是你想取得遠程信息的那個套接字描述符。
addr 是一個指向struct sockaddr (或是struct sockaddr_in)的指針。
addrlen 是一個指向int 的指針,應該賦于sizeof(struct sockaddr)的大小。
?
?
總結
以上是生活随笔為你收集整理的linux网络编程--数据结构与函数原型的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Springmvc架构详解
- 下一篇: 深信服 linux软件开发面试题整理