Socket編程函數(shù)集
accept(接受socket連線)
相關(guān)函數(shù)
socket,bind,listen,connect
表頭文件
#include<sys/types.h>
#include<sys/socket.h>
定義函數(shù)
int accept(int s,struct sockaddr * addr,int * addrlen);
函數(shù)說明
accept()用來接受參數(shù)s的socket連線。參數(shù)s的socket必需先經(jīng)bind()、listen()函數(shù)處理過,當(dāng)有連線進(jìn)來時(shí)accept()會(huì)返回一個(gè)新的socket處理代碼,往后的數(shù)據(jù)傳送與讀取就是經(jīng)由新的socket處理,而原來參數(shù)s的socket能繼續(xù)使用accept()來接受新的連線要求。連線成功時(shí),參數(shù)addr所指的結(jié)構(gòu)會(huì)被系統(tǒng)填入遠(yuǎn)程主機(jī)的地址數(shù)據(jù),參數(shù)addrlen為scokaddr的結(jié)構(gòu)長度。關(guān)于結(jié)構(gòu)sockaddr的定義請(qǐng)參考bind()。
返回值
成功則返回新的socket處理代碼,失敗返回-1,錯(cuò)誤原因存于errno中。
錯(cuò)誤代碼
EBADF參數(shù)s 非合法socket處理代碼。
EFAULT參數(shù)addr指針指向無法存取的內(nèi)存空間。
ENOTSOCK參數(shù)s為一文件描述詞,非socket。
EOPNOTSUPP指定的socket并非SOCK_STREAM。
EPERM防火墻拒絕此連線。
ENOBUFS 系統(tǒng)的緩沖內(nèi)存不足。
ENOMEM核心內(nèi)存不足。
范例
參考listen()。
bind(對(duì)socket定位)
相關(guān)函數(shù)
socket,accept,connect,listen
表頭文件
#include<sys/types.h>
#include<sys/socket.h>
定義函數(shù)
int bind(int sockfd,struct sockaddr * my_addr,int addrlen);
函數(shù)說明
bind()用來設(shè)置給參數(shù)sockfd的socket一個(gè)名稱。此名稱由參數(shù)my_addr指向一sockaddr結(jié)構(gòu),對(duì)于不同的socket domain定義了一個(gè)通用的數(shù)據(jù)結(jié)構(gòu)。
struct sockaddr {
unsigned short int sa_family;
char sa_data[14];
};
sa_family 為調(diào)用socket()時(shí)的domain參數(shù),即AF_xxxx值。
sa_data 最多使用14個(gè)字符長度。
此sockaddr結(jié)構(gòu)會(huì)因使用不同的socket domain而有不同結(jié)構(gòu)定義,例如使用AF_INET domain,其socketaddr結(jié)構(gòu)定義便為
struct socketaddr_in {
unsigned short int sin_family;
uint16_t sin_port;
struct in_addr sin_addr;
unsigned char sin_zero[8];
};
struct in_addr {
uint32_t s_addr;
};
sin_family 即為sa_family
sin_port 為使用的port編號(hào)
sin_addr.s_addr 為IP 地址
sin_zero 未使用。
參數(shù)說明
addrlen為sockaddr的結(jié)構(gòu)長度。
返回值
成功則返回0,失敗返回-1,錯(cuò)誤原因存于errno中。
錯(cuò)誤代碼
EBADF參數(shù)sockfd 非合法socket處理代碼。
EACCESS權(quán)限不足
ENOTSOCK參數(shù)sockfd為一文件描述詞,非socket。
范例
參考listen()
connect(建立socket連線)
相關(guān)函數(shù)
socket,bind,listen
表頭文件
#include<sys/types.h>
#include<sys/socket.h>
定義函數(shù)
int connect (int sockfd,struct sockaddr * serv_addr,int addrlen);
函數(shù)說明
connect()用來將參數(shù)sockfd 的socket 連至參數(shù)serv_addr 指定的網(wǎng)絡(luò)地址。結(jié)構(gòu)sockaddr請(qǐng)參考bind()。參數(shù)addrlen為sockaddr的結(jié)構(gòu)長度。
返回值
成功則返回0,失敗返回-1,錯(cuò)誤原因存于errno中。
錯(cuò)誤代碼
EBADF參數(shù)sockfd 非合法socket處理代碼
EFAULT參數(shù)serv_addr指針指向無法存取的內(nèi)存空間
ENOTSOCK參數(shù)sockfd為一文件描述詞,非socket。
EISCONN參數(shù)sockfd的socket已是連線狀態(tài)
ECONNREFUSED連線要求被server端拒絕。
ETIMEDOUT企圖連線的操作超過限定時(shí)間仍未有響應(yīng)。
ENETUNREACH無法傳送數(shù)據(jù)包至指定的主機(jī)。
EAFNOSUPPORT sockaddr結(jié)構(gòu)的sa_family不正確。
EALREADY socket為不可阻斷且先前的連線操作還未完成。
范例
/* 利用socket的TCP client
* 此程序會(huì)連線TCP server,并將鍵盤輸入的字符串傳送給server。
* TCP server范例請(qǐng)參考listen()。
*/
#include<sys/stat.h>
#include<fcntl.h>
#include<unistd.h>
#include<sys/types.h>
#include<sys/socket.h>
#include<netinet/in.h>
#include<arpa/inet.h>
#define PORT 1234
#define SERVER_IP “127.0.0.1”
main()
{
int s;
struct sockaddr_in addr;
char buffer[256];
if ((s = socket(AF_INET,SOCK_STREAM,0))<0)
{
perror(“socket”);
exit(1);
}
/* 填寫sockaddr_in結(jié)構(gòu)*/
bzero(&addr,sizeof(addr));
addr.sin_family = AF_INET;
addr.sin_port = htons(PORT);
addr.sin_addr.s_addr = inet_addr(SERVER_IP); /* 嘗試連線*/
if (connect(s,&addr,sizeof(addr))<0)
{
perror(“connect”);
exit(1);
}
/* 接收由server端傳來的信息*/
recv(s,buffer,sizeof(buffer),0);
printf(“%s\n”,buffer);
while(1)
{
bzero(buffer, sizeof(buffer));
/* 從標(biāo)準(zhǔn)輸入設(shè)備取得字符串*/
read(STDIN_FILENO, buffer, sizeof(buffer));
/* 將字符串傳給server端*/
if (send(s, buffer, sizeof(buffer), 0)<0)
{
perror(“send”);
exit(1);
}
}
}
執(zhí)行
$ ./connect
Welcome to server!
hi I am client! /*鍵盤輸入*/
/*<Ctrl+C>中斷程序*/
endprotoent(結(jié)束網(wǎng)絡(luò)協(xié)議數(shù)據(jù)的讀?。?div style="height:15px;">
相關(guān)函數(shù)
getprotoent,getprotobyname,getprotobynumber,setprotoent
表頭文件
#include<netdb.h>
定義函數(shù)
void endprotoent(void);
函數(shù)說明
endprotoent()用來關(guān)閉由getprotoent()打開的文件。
返回值
無返回值
范例
參考getprotoent()
endservent(結(jié)束網(wǎng)絡(luò)服務(wù)數(shù)據(jù)的讀?。?div style="height:15px;">
相關(guān)函數(shù)
getservent,getservbyname,getservbyport,setservent
表頭文件
#include<netdb.h>
定義函數(shù)
void endservent(void);
函數(shù)說明
endservent()用來關(guān)閉由getservent()所打開的文件。
返回值
無返回值
范例
參考getservent()。
getsockopt(取得socket狀態(tài))
相關(guān)函數(shù)
setsockopt
表頭文件
#include<sys/types.h>
#include<sys/socket.h>
定義函數(shù)
int getsockopt(int s,int level,int optname,void* optval,socklen_t* optlen);
函數(shù)說明
getsockopt()會(huì)將參數(shù)s所指定的socket狀態(tài)返回。參數(shù)optname代表欲取得何種選項(xiàng)狀態(tài),而參數(shù)optval則指向欲保存結(jié)果的內(nèi)存地址,參數(shù)optlen則為該空間的大小。參數(shù)level、optname請(qǐng)參考setsockopt()。
返回值
成功則返回0,若有錯(cuò)誤則返回-1,錯(cuò)誤原因存于errno
錯(cuò)誤代碼
EBADF參數(shù)s 并非合法的socket處理代碼
ENOTSOCK參數(shù)s為一文件描述詞,非socket
ENOPROTOOPT參數(shù)optname指定的選項(xiàng)不正確
EFAULT參數(shù)optval指針指向無法存取的內(nèi)存空間
范例
#include<sys/types.h>
#include<sys/socket.h>
main()
{
int s,optval,optlen = sizeof(int);
if ((s = socket(AF_INET,SOCK_STREAM,0))<0)
perror(“socket”);
getsockopt(s,SOL_SOCKET,SO_TYPE,&optval,&optlen);
printf(“optval = %d\n”,optval);
close(s);
}
執(zhí)行
optval = 1 /*SOCK_STREAM的定義正是此值*/
htonl(將32位主機(jī)字符順序轉(zhuǎn)換成網(wǎng)絡(luò)字符順序)
相關(guān)函數(shù)
htons,ntohl,ntohs
表頭文件
#include<netinet/in.h>
定義函數(shù)
unsigned long int htonl(unsigned long int hostlong);
函數(shù)說明
Htonl()用來將參數(shù)指定的32位hostlong 轉(zhuǎn)換成網(wǎng)絡(luò)字符順序。
返回值
返回對(duì)應(yīng)的網(wǎng)絡(luò)字符順序。
范例
參考getservbyport()或connect()。
htons(將16位主機(jī)字符順序轉(zhuǎn)換成網(wǎng)絡(luò)字符順序)
相關(guān)函數(shù)
htonl,ntohl,ntohs
表頭文件
#include<netinet/in.h>
定義函數(shù)
unsigned short int htons(unsigned short int hostshort);
函數(shù)說明
htons()用來將參數(shù)指定的16位hostshort轉(zhuǎn)換成網(wǎng)絡(luò)字符順序。
返回值
返回對(duì)應(yīng)的網(wǎng)絡(luò)字符順序。
范例
參考connect()。
inet_addr(將網(wǎng)絡(luò)地址轉(zhuǎn)成二進(jìn)制的數(shù)字)
相關(guān)函數(shù)
inet_aton,inet_ntoa
表頭文件
#include<sys/socket.h>
#include<netinet/in.h>
#include<arpa/inet.h>
定義函數(shù)
unsigned long int inet_addr(const char *cp);
函數(shù)說明
inet_addr()用來將參數(shù)cp所指的網(wǎng)絡(luò)地址字符串轉(zhuǎn)換成網(wǎng)絡(luò)所使用的二進(jìn)制數(shù)字。網(wǎng)絡(luò)地址字符串是以數(shù)字和點(diǎn)組成的字符串,例如:“163.13.132.68”。
返回值
成功則返回對(duì)應(yīng)的網(wǎng)絡(luò)二進(jìn)制的數(shù)字,失敗返回-1。
inet_aton(將網(wǎng)絡(luò)地址轉(zhuǎn)成網(wǎng)絡(luò)二進(jìn)制的數(shù)字)
相關(guān)函數(shù)
inet_addr,inet_ntoa
表頭文件
#include<sys/scoket.h>
#include<netinet/in.h>
#include<arpa/inet.h>
定義函數(shù)
int inet_aton(const char * cp,struct in_addr *inp);
函數(shù)說明
inet_aton()用來將參數(shù)cp所指的網(wǎng)絡(luò)地址字符串轉(zhuǎn)換成網(wǎng)絡(luò)使用的二進(jìn)制的數(shù)字,然后存于參數(shù)inp所指的in_addr結(jié)構(gòu)中。
結(jié)構(gòu)in_addr定義如下
struct in_addr {
unsigned long int s_addr;
};
返回值
成功則返回非0值,失敗則返回0。
inet_ntoa(將網(wǎng)絡(luò)二進(jìn)制的數(shù)字轉(zhuǎn)換成網(wǎng)絡(luò)地址)
相關(guān)函數(shù)
inet_addr,inet_aton
表頭文件
#include<sys/socket.h>
#include<netinet/in.h>
#include<arpa/inet.h>
定義函數(shù)
char * inet_ntoa(struct in_addr in);
函數(shù)說明
inet_ntoa()用來將參數(shù)in所指的網(wǎng)絡(luò)二進(jìn)制的數(shù)字轉(zhuǎn)換成網(wǎng)絡(luò)地址,然后將指向此網(wǎng)絡(luò)地址字符串的指針返回。
返回值
成功則返回字符串指針,失敗則返回NULL。
listen(等待連接)
相關(guān)函數(shù)
socket,bind,accept,connect
表頭文件
#include<sys/socket.h>
定義函數(shù)
int listen(int s,int backlog);
函數(shù)說明
listen()用來等待參數(shù)s 的socket連線。參數(shù)backlog指定同時(shí)能處理的最大連接要求,如果連接數(shù)目達(dá)此上限則client端將收到ECONNREFUSED的錯(cuò)誤。Listen()并未開始接收連線,只是設(shè)置socket為listen模式,真正接收client端連線的是accept()。通常listen()會(huì)在socket(),bind()之后調(diào)用,接著才調(diào)用accept()。
返回值
成功則返回0,失敗返回-1,錯(cuò)誤原因存于errno
附加說明
listen()只適用SOCK_STREAM或SOCK_SEQPACKET的socket類型。如果socket為AF_INET則參數(shù)backlog 最大值可設(shè)至128。
錯(cuò)誤代碼
EBADF參數(shù)sockfd非合法socket處理代碼
EACCESS權(quán)限不足
EOPNOTSUPP指定的socket并未支援listen模式。
范例
#include<sys/types.h>
#include<sys/socket.h>
#include<netinet/in.h>
#include<arpa/inet.h>
#include<unistd.h>
#define PORT 1234
#define MAXSOCKFD 10
main()
{
int sockfd,newsockfd,is_connected[MAXSOCKFD],fd;
struct sockaddr_in addr;
int addr_len = sizeof(struct sockaddr_in);
fd_set readfds;
char buffer[256];
char msg[ ] =”Welcome to server!”;
if ((sockfd = socket(AF_INET,SOCK_STREAM,0))<0)
{
perror(“socket”);
exit(1);
}
bzero(&addr,sizeof(addr));
addr.sin_family =AF_INET;
addr.sin_port = htons(PORT);
addr.sin_addr.s_addr = htonl(INADDR_ANY);
if (bind(sockfd,&addr,sizeof(addr))<0)
{
perror(“connect”);
exit(1);
}
if (listen(sockfd,3)<0)
{
perror(“listen”);
exit(1);
}
for (fd=0; fd<MAXSOCKFD; fd++)
is_connected[fd]=0;
while(1)
{
FD_ZERO(&readfds);
FD_SET(sockfd,&readfds);
for (fd=0; fd<MAXSOCKFD; fd++)
if (is_connected[fd])
FD_SET(fd,&readfds);
if (!select(MAXSOCKFD, &readfds, NULL, NULL, NULL))
continue;
for (fd=0;fd<MAXSOCKFD;fd++)
if (FD_ISSET(fd,&readfds))
{
if (sockfd = =fd)
{
if((newsockfd = accept (sockfd,&addr,&addr_len))<0)
perror(“accept”);
write(newsockfd,msg,sizeof(msg));
is_connected[newsockfd] =1;
printf(“cnnect from %s\n”,inet_ntoa(addr.sin_addr));
}
else
{
bzero(buffer, sizeof(buffer));
if (read(fd,buffer,sizeof(buffer))<=0)
{
printf(“connect closed.\n”);
is_connected[fd]=0;
close(fd);
}
else
printf(“%s”,buffer);
}
}
}
}
執(zhí)行
$ ./listen
connect from 127.0.0.1
hi I am client
connected closed.
ntohl(將32位網(wǎng)絡(luò)字符順序轉(zhuǎn)換成主機(jī)字符順序)
相關(guān)函數(shù)
htonl,htons,ntohs
表頭文件
#include<netinet/in.h>
定義函數(shù)
unsigned long int ntohl(unsigned long int netlong);
函數(shù)說明
ntohl()用來將參數(shù)指定的32位netlong轉(zhuǎn)換成主機(jī)字符順序。
返回值
返回對(duì)應(yīng)的主機(jī)字符順序。
范例
參考getservent()。
ntohs(將16位網(wǎng)絡(luò)字符順序轉(zhuǎn)換成主機(jī)字符順序)
相關(guān)函數(shù)
htonl,htons,ntohl
表頭文件
#include<netinet/in.h>
定義函數(shù)
unsigned short int ntohs(unsigned short int netshort);
函數(shù)說明
ntohs()用來將參數(shù)指定的16位netshort轉(zhuǎn)換成主機(jī)字符順序。
返回值
返回對(duì)應(yīng)的主機(jī)順序。
范例
參考getservent()。
recv(經(jīng)socket接收數(shù)據(jù))
相關(guān)函數(shù)
recvfrom,recvmsg,send,sendto,socket
表頭文件
#include<sys/types.h>
#include<sys/socket.h>
定義函數(shù)
int recv(int s,void *buf, int len, unsigned int flags);
函數(shù)說明
recv()用來接收遠(yuǎn)端主機(jī)經(jīng)指定的socket傳來的數(shù)據(jù),并把數(shù)據(jù)存到由參數(shù)buf 指向的內(nèi)存空間,參數(shù)len為可接收數(shù)據(jù)的最大長度。
參數(shù)
及
返回值
flags一般設(shè)0。其他數(shù)值定義如下:
MSG_OOB接收以out-of-band 送出的數(shù)據(jù)。
MSG_PEEK返回來的數(shù)據(jù)并不會(huì)在系統(tǒng)內(nèi)刪除,如果再調(diào)用recv()會(huì)返回相同的數(shù)據(jù)內(nèi)容。
MSG_WAITALL強(qiáng)迫接收到len大小的數(shù)據(jù)后才能返回,除非有錯(cuò)誤或信號(hào)產(chǎn)生。
MSG_NOSIGNAL此操作不愿被SIGPIPE信號(hào)中斷返回值成功則返回接收到的字符數(shù),失敗返回-1,錯(cuò)誤原因存于errno中。
錯(cuò)誤代碼
EBADF參數(shù)s非合法的socket處理代碼
FAULT參數(shù)中有一指針指向無法存取的內(nèi)存空間
ENOTSOCK參數(shù)s為一文件描述詞,非socket。
EINTR被信號(hào)所中斷
EAGAIN此動(dòng)作會(huì)令進(jìn)程阻斷,但參數(shù)s的socket為不可阻斷
ENOBUFS系統(tǒng)的緩沖內(nèi)存不足。
ENOMEM核心內(nèi)存不足
EINVAL傳給系統(tǒng)調(diào)用的參數(shù)不正確。
范例
參考listen()。
recvfrom(經(jīng)socket接收數(shù)據(jù))
相關(guān)函數(shù)
recv,recvmsg,send,sendto,socket
表頭文件
#include<sys/types.h>
#include<sys/socket.h>
定義函數(shù)
int recvfrom(int s,void *buf,int len,unsigned int flags ,struct sockaddr *from ,int *fromlen);
函數(shù)說明
recv()用來接收遠(yuǎn)程主機(jī)經(jīng)指定的socket 傳來的數(shù)據(jù),并把數(shù)據(jù)存到由參數(shù)buf 指向的內(nèi)存空間,參數(shù)len 為可接收數(shù)據(jù)的最大長度。參數(shù)flags 一般設(shè)0,其他數(shù)值定義請(qǐng)參考recv()。參數(shù)from用來指定欲傳送的網(wǎng)絡(luò)地址,結(jié)構(gòu)sockaddr 請(qǐng)參考bind()。參數(shù)fromlen為sockaddr的結(jié)構(gòu)長度。
返回值
成功則返回接收到的字符數(shù),失敗則返回-1,錯(cuò)誤原因存于errno中。
錯(cuò)誤代碼
EBADF參數(shù)s非合法的socket處理代碼
EFAULT參數(shù)中有一指針指向無法存取的內(nèi)存空間。
ENOTSOCK參數(shù)s為一文件描述詞,非socket。
EINTR被信號(hào)所中斷。
EAGAIN此動(dòng)作會(huì)令進(jìn)程阻斷,但參數(shù)s的socket為不可阻斷。
ENOBUFS系統(tǒng)的緩沖內(nèi)存不足
ENOMEM核心內(nèi)存不足
EINVAL傳給系統(tǒng)調(diào)用的參數(shù)不正確。
范例
/*利用socket的UDP client
* 此程序會(huì)連線UDP server,并將鍵盤輸入的字符串傳給server。
* UDP server 范例請(qǐng)參考sendto()。
*/
#include<sys/stat.h>
#include<fcntl.h>
#include<unistd.h>
#include<sys/typs.h>
#include<sys/socket.h>
#include<netinet/in.h>
#include<arpa/inet.h>
#define PORT 2345
#define SERVER_IP “127.0.0.1”
main()
{
int s,len;
struct sockaddr_in addr;
int addr_len =sizeof(struct sockaddr_in);
char buffer[256];
/* 建立socket*/
if ((s = socket(AF_INET,SOCK_DGRAM,0))<0)
{
perror(“socket”);
exit(1);
}
/* 填寫sockaddr_in*/
bzero(&addr,sizeof(addr));
addr.sin_family = AF_INET;
addr.sin_port = htons(PORT);
addr.sin_addr.s_addr = inet_addr(SERVER_IP);
while(1)
{
bzero(buffer,sizeof(buffer));
/* 從標(biāo)準(zhǔn)輸入設(shè)備取得字符串*/
len =read(STDIN_FILENO,buffer,sizeof(buffer));
/* 將字符串傳送給server端*/
sendto(s,buffer,len,0,&addr,addr_len);
/* 接收server端返回的字符串*/
len = recvfrom(s,buffer,sizeof(buffer),0,&addr,&addr_len);
printf(“receive: %s”,buffer);
}
}
執(zhí)行
(先執(zhí)行udp server 再執(zhí)行udp client)
hello /*從鍵盤輸入字符串*/
receive: hello /*server端返回來的字符串*/
recvmsg(經(jīng)socket接收數(shù)據(jù))
相關(guān)函數(shù)
recv,recvfrom,send,sendto,sendmsg,socket
表頭文件
#include<sys/types.h>
#include<sys/socktet.h>
定義函數(shù)
int recvmsg(int s,struct msghdr *msg,unsigned int flags);
函數(shù)說明
recvmsg()用來接收遠(yuǎn)程主機(jī)經(jīng)指定的socket傳來的數(shù)據(jù)。參數(shù)s為已建立好連線的socket,如果利用UDP協(xié)議則不需經(jīng)過連線操作。參數(shù)msg指向欲連線的數(shù)據(jù)結(jié)構(gòu)內(nèi)容,參數(shù)flags一般設(shè)0,詳細(xì)描述請(qǐng)參考send()。關(guān)于結(jié)構(gòu)msghdr的定義請(qǐng)參考sendmsg()。
返回值
成功則返回接收到的字符數(shù),失敗則返回-1,錯(cuò)誤原因存于errno中。
錯(cuò)誤代碼
EBADF參數(shù)s非合法的socket處理代碼。
EFAULT參數(shù)中有一指針指向無法存取的內(nèi)存空間
ENOTSOCK參數(shù)s為一文件描述詞,非socket。
EINTR被信號(hào)所中斷。
EAGAIN此操作會(huì)令進(jìn)程阻斷,但參數(shù)s的socket為不可阻斷。
ENOBUFS系統(tǒng)的緩沖內(nèi)存不足
ENOMEM核心內(nèi)存不足
EINVAL傳給系統(tǒng)調(diào)用的參數(shù)不正確。
范例
參考recvfrom()。
send(經(jīng)socket傳送數(shù)據(jù))
相關(guān)函數(shù)
sendto,sendmsg,recv,recvfrom,socket
表頭文件
#include<sys/types.h>
#include<sys/socket.h>
定義函數(shù)
int send(int s,const void * msg,int len,unsigned int falgs);
函數(shù)說明
send()用來將數(shù)據(jù)由指定的socket 傳給對(duì)方主機(jī)。參數(shù)s為已建立好連接的socket。參數(shù)msg指向欲連線的數(shù)據(jù)內(nèi)容,參數(shù)len則為數(shù)據(jù)長度。參數(shù)flags一般設(shè)0,其他數(shù)值定義如下:
MSG_OOB傳送的數(shù)據(jù)以out-of-band 送出。
MSG_DONTROUTE取消路由表查詢
MSG_DONTWAIT設(shè)置為不可阻斷運(yùn)作
MSG_NOSIGNAL此動(dòng)作不愿被SIGPIPE 信號(hào)中斷。
返回值
成功則返回實(shí)際傳送出去的字符數(shù),失敗返回-1。錯(cuò)誤原因存于errno
錯(cuò)誤代碼
EBADF參數(shù)s 非合法的socket處理代碼。
EFAULT參數(shù)中有一指針指向無法存取的內(nèi)存空間
ENOTSOCK參數(shù)s為一文件描述詞,非socket。
EINTR被信號(hào)所中斷。
EAGAIN此操作會(huì)令進(jìn)程阻斷,但參數(shù)s的socket為不可阻斷。
ENOBUFS系統(tǒng)的緩沖內(nèi)存不足
ENOMEM核心內(nèi)存不足
EINVAL傳給系統(tǒng)調(diào)用的參數(shù)不正確。
范例
參考connect()
sendmsg(經(jīng)socket傳送數(shù)據(jù))
相關(guān)函數(shù)
send,sendto,recv,recvfrom,recvmsg,socket
表頭文件
#include<sys/types.h>
#include<sys/socket.h>
定義函數(shù)
int sendmsg(int s,const strcut msghdr *msg,unsigned int flags);
函數(shù)說明
sendmsg()用來將數(shù)據(jù)由指定的socket傳給對(duì)方主機(jī)。參數(shù)s為已建立好連線的socket,如果利用UDP協(xié)議則不需經(jīng)過連線操作。參數(shù)msg 指向欲連線的數(shù)據(jù)結(jié)構(gòu)內(nèi)容,參數(shù)flags一般默認(rèn)為0,詳細(xì)描述請(qǐng)參考send()。
結(jié)構(gòu)msghdr定義如下
struct msghdr {
void *msg_name; /*Address to send to /receive from . */
socklen_t msg_namelen; /* Length of addres data */
strcut iovec * msg_iov; /* Vector of data to send/receive into */
size_t msg_iovlen; /* Number of elements in the vector */
void * msg_control; /* Ancillary dat */
size_t msg_controllen; /* Ancillary data buffer length */
int msg_flags; /* Flags on received message */
};
返回值
成功則返回實(shí)際傳送出去的字符數(shù),失敗返回-1,錯(cuò)誤原因存于errno
錯(cuò)誤代碼
EBADF參數(shù)s 非合法的socket處理代碼。
EFAULT參數(shù)中有一指針指向無法存取的內(nèi)存空間
ENOTSOCK參數(shù)s為一文件描述詞,非socket。
EINTR被信號(hào)所中斷。
EAGAIN此操作會(huì)令進(jìn)程阻斷,但參數(shù)s的socket為不可阻斷。
ENOBUFS系統(tǒng)的緩沖內(nèi)存不足
ENOMEM核心內(nèi)存不足
EINVAL傳給系統(tǒng)調(diào)用的參數(shù)不正確。
范例
參考sendto()。
sendto(經(jīng)socket傳送數(shù)據(jù))
相關(guān)函數(shù)
send , sendmsg,recv , recvfrom , socket
表頭文件
#include < sys/types.h >
#include < sys/socket.h >
定義函數(shù)
int sendto ( int s , const void * msg, int len, unsigned int flags, const struct sockaddr * to , int tolen ) ;
函數(shù)說明
sendto() 用來將數(shù)據(jù)由指定的socket傳給對(duì)方主機(jī)。參數(shù)s為已建好連線的socket,如果利用UDP協(xié)議則不需經(jīng)過連線操作。參數(shù)msg指向欲連線的數(shù)據(jù)內(nèi)容,參數(shù)flags 一般設(shè)0,詳細(xì)描述請(qǐng)參考send()。參數(shù)to用來指定欲傳送的網(wǎng)絡(luò)地址,結(jié)構(gòu)sockaddr請(qǐng)參考bind()。參數(shù)tolen為sockaddr的結(jié)果長度。
返回值
成功則返回實(shí)際傳送出去的字符數(shù),失敗返回-1,錯(cuò)誤原因存于errno 中。
錯(cuò)誤代碼
EBADF參數(shù)s非法的socket處理代碼。
EFAULT參數(shù)中有一指針指向無法存取的內(nèi)存空間。
WNOTSOCK canshu s為一文件描述詞,非socket。
EINTR被信號(hào)所中斷。
EAGAIN此動(dòng)作會(huì)令進(jìn)程阻斷,但參數(shù)s的soket為補(bǔ)課阻斷的。
ENOBUFS系統(tǒng)的緩沖內(nèi)存不足。
EINVAL傳給系統(tǒng)調(diào)用的參數(shù)不正確。
范例
#include < sys/types.h >
#include < sys/socket.h >
# include <netinet.in.h>
#include <arpa.inet.h>
#define PORT 2345 /*使用的port*/
main()
{
int sockfd,len;
struct sockaddr_in addr;
char buffer[256];
/*建立socket*/
if (sockfd=socket (AF_INET,SOCK_DGRAM,0))<0}
{
perror (“socket”);
exit(1);
}
/*填寫sockaddr_in 結(jié)構(gòu)*/
bzero ( &addr, sizeof(addr) );
addr.sin_family=AF_INET;
addr.sin_port=htons(PORT);
addr.sin_addr=hton1(INADDR_ANY) ;
if (bind(sockfd, &addr, sizeof(addr))<0)
{
perror(“connect”);
exit(1);
}
while(1)
{
bezro(buffer,sizeof(buffer));
len = recvfrom(socket,buffer,sizeof(buffer), 0 , &addr &addr_len);
/*顯示client端的網(wǎng)絡(luò)地址*/
printf(“receive from %s\n “ , inet_ntoa( addr.sin_addr));
/*將字串返回給client端*/
sendto(sockfd,buffer,len,0,&addr,addr_len);”
}
}
執(zhí)行
請(qǐng)參考recvfrom()
setprotoent(打開網(wǎng)絡(luò)協(xié)議的數(shù)據(jù)文件)
相關(guān)函數(shù)
getprotobyname, getprotobynumber, endprotoent
表頭文件
#include <netdb.h>
定義函數(shù)
void setprotoent (int stayopen);
函數(shù)說明
setprotoent()用來打開/etc/protocols,如果參數(shù)stayopen值為1,則接下來的getprotobyname()或getprotobynumber()將不會(huì)自動(dòng)關(guān)閉此文件。
setservent(打開主機(jī)網(wǎng)絡(luò)服務(wù)的數(shù)據(jù)文件)
相關(guān)函數(shù)
getservent, getservbyname, getservbyport, endservent
表頭文件
#include < netdb.h >
定義函數(shù)
void setservent (int stayopen);
函數(shù)說明
setservent()用來打開/etc/services,如果參數(shù)stayopen值為1,則接下來的getservbyname()或getservbyport()將補(bǔ)回自動(dòng)關(guān)閉文件。
setsockopt(設(shè)置socket狀態(tài))
相關(guān)函數(shù)
getsockopt
表頭文件
#include<sys/types.h>
#include<sys/socket.h>
定義函數(shù)
int setsockopt(int s,int level,int optname,const void * optval,,socklen_toptlen);
函數(shù)說明
setsockopt()用來設(shè)置參數(shù)s所指定的socket狀態(tài)。參數(shù)level代表欲設(shè)置的網(wǎng)絡(luò)層,一般設(shè)成SOL_SOCKET以存取socket層。參數(shù)optname代表欲設(shè)置的選項(xiàng),有下列幾種數(shù)值:
SO_DEBUG打開或關(guān)閉排錯(cuò)模式
SO_REUSEADDR允許在bind()過程中本地地址可重復(fù)使用
SO_TYPE返回socket形態(tài)。
SO_ERROR返回socket已發(fā)生的錯(cuò)誤原因
SO_DONTROUTE送出的數(shù)據(jù)包不要利用路由設(shè)備來傳輸。
SO_BROADCAST使用廣播方式傳送
SO_SNDBUF設(shè)置送出的暫存區(qū)大小
SO_RCVBUF設(shè)置接收的暫存區(qū)大小
SO_KEEPALIVE定期確定連線是否已終止。
SO_OOBINLINE當(dāng)接收到OOB 數(shù)據(jù)時(shí)會(huì)馬上送至標(biāo)準(zhǔn)輸入設(shè)備
SO_LINGER確保數(shù)據(jù)安全且可靠的傳送出去。
參數(shù)
optval代表欲設(shè)置的值,參數(shù)optlen則為optval的長度。
返回值
成功則返回0,若有錯(cuò)誤則返回-1,錯(cuò)誤原因存于errno。
附加說明
EBADF參數(shù)s并非合法的socket處理代碼。
ENOTSOCK參數(shù)s為一文件描述詞,非socket。
ENOPROTOOPT參數(shù)optname指定的選項(xiàng)不正確。
EFAULT參數(shù)optval指針指向無法存取的內(nèi)存空間。
范例
參考getsockopt()。
shutdown(終止socket通信)
相關(guān)函數(shù)
socket,connect
表頭文件
#include<sys/socket.h>
定義函數(shù)
int shutdown(int s,int how);
函數(shù)說明
shutdown()用來終止參數(shù)s所指定的socket連線。參數(shù)s是連線中的socket處理代碼,參數(shù)how有下列幾種情況:
how=0 終止讀取操作。
how=1 終止傳送操作
how=2 終止讀取及傳送操作
返回值
成功則返回0,失敗返回-1,錯(cuò)誤原因存于errno。
錯(cuò)誤代碼
EBADF參數(shù)s不是有效的socket處理代碼。
ENOTSOCK參數(shù)s為一文件描述詞,非socket。
ENOTCONN參數(shù)s指定的socket并未連線。
socket(建立一個(gè)socket通信)
相關(guān)函數(shù)
accept,bind,connect,listen
表頭文件
#include<sys/types.h>
#include<sys/socket.h>
定義函數(shù)
int socket(int domain,int type,int protocol);
函數(shù)說明
socket()用來建立一個(gè)新的socket,也就是向系統(tǒng)注冊(cè),通知系統(tǒng)建立一通信端口。參數(shù)domain 指定使用何種的地址類型,完整的定義在/usr/include/bits/socket.h 內(nèi),底下是常見的協(xié)議:
PF_UNIX/PF_LOCAL/AF_UNIX/AF_LOCAL UNIX 進(jìn)程通信協(xié)議。
PF_INET?AF_INET Ipv4網(wǎng)絡(luò)協(xié)議。
PF_INET6/AF_INET6 Ipv6 網(wǎng)絡(luò)協(xié)議。
PF_IPX/AF_IPX IPX-Novell協(xié)議。
PF_NETLINK/AF_NETLINK核心用戶接口裝置。
PF_X25/AF_X25 ITU-T X.25/ISO-8208 協(xié)議。
PF_AX25/AF_AX25業(yè)余無線AX.25協(xié)議。
PF_ATMPVC/AF_ATMPVC存取原始ATM PVCs。
PF_APPLETALK/AF_APPLETALK appletalk(DDP)協(xié)議。
PF_PACKET/AF_PACKET初級(jí)封包接口
參數(shù)
type有下列幾種數(shù)值:
SOCK_STREAM提供雙向連續(xù)且可信賴的數(shù)據(jù)流,即TCP。支持
OOB 機(jī)制,在所有數(shù)據(jù)傳送前必須使用connect()來建立連線狀態(tài)。
SOCK_DGRAM使用不連續(xù)不可信賴的數(shù)據(jù)包連接
SOCK_SEQPACKET提供連續(xù)可信賴的數(shù)據(jù)包連接
SOCK_RAW提供原始網(wǎng)絡(luò)協(xié)議存取
SOCK_RDM提供可信賴的數(shù)據(jù)包連接
SOCK_PACKET提供和網(wǎng)絡(luò)驅(qū)動(dòng)程序直接通信。
protocol用來指定socket所使用的傳輸協(xié)議編號(hào),通常此參考不用管它,設(shè)
返回值
成功則返回socket處理代碼,失敗返回-1。
錯(cuò)誤代碼
EPROTONOSUPPORT參數(shù)domain指定的類型不支持參數(shù)type或protocol指定的協(xié)議
ENFILE核心內(nèi)存不足,無法建立新的socket結(jié)構(gòu);
EMFILE進(jìn)程文件表溢出,無法再建立新的socket
EACCESS權(quán)限不足,無法建立type或protocol指定的協(xié)議
ENOBUFS/ENOMEM 內(nèi)存不足
EINVAL參數(shù)domain/type/protocol不合法
范例
參考connect()。