热门话题

Php 研究室

Linux Socket函数简明参考(3)    作者:xieaotian发表于2010-02-07 10:46:32

	   

12. listen(等待连接)
相关函数 socket,bind,accept,connect

表头文件 #include

定义函数 int listen(int s,int backlog);

函数说明 listen ()用来等待参数s 的socket连线。参数backlog指定同时能处理的最大连接要求,如果连接数目达此上限则client端将收到ECONNREFUSED的错误。 Listen()并未开始接收连线,只是设置socket为listen模式,真正接收client端连线的是accept()。通常listen()会 在socket(),bind()之后调用,接着才调用accept()。

返回值 成功则返回0,失败返回-1,错误原因存于errno

附加说明 listen()只适用SOCK_STREAM或SOCK_SEQPACKET的socket类型。如果socket为AF_INET则参数backlog 最大值可设至128。

错误代码

* EBADF 参数sockfd非合法socket处理代码[*]EACCESS 权限不足[*]EOPNOTSUPP 指定的socket并未支援listen模式


范例
Cpp代码

1. #include
2. #include
3. #include
4. #include
5. #include
6. #define PORT 1234
7. #define MAXSOCKFD 10
8. main()
9. {
10. int sockfd,newsockfd,is_connected[MAXSOCKFD],fd;
11. struct sockaddr_in addr;
12. int addr_len = sizeof(struct sockaddr_in);
13. fd_set readfds;
14. char buffer[256];
15. char msg[ ] =”Welcome to server!”;
16. if ((sockfd = socket(AF_INET,SOCK_STREAM,0))<0){
17. perror(“socket”);
18. exit(1);
19. }
20. bzero(&addr,sizeof(addr));
21. addr.sin_family =AF_INET;
22. addr.sin_port = htons(PORT);
23. addr.sin_addr.s_addr = htonl(INADDR_ANY);
24. if(bind(sockfd,&addr,sizeof(addr))<0){
25. perror(“connect”);
26. exit(1);
27. }
28. if(listen(sockfd,3)<0){
29. perror(“listen”);
30. exit(1);
31. }
32. for(fd=0;fd 33. is_connected[fd]=0;
34. while(1){
35. FD_ZERO(&readfds);
36. FD_SET(sockfd,&readfds);
37. for(fd=0;fd 38. if(is_connected[fd])
39. FD_SET(fd,&readfds);
40. if(!select(MAXSOCKFD,&readfds,NULL,NULL,NULL))
41. continue;
42. for(fd=0;fd 43. if(FD_ISSET(fd,&readfds)){
44. if(sockfd = =fd){
45. if((newsockfd = accept (sockfd,&addr,&addr_len))<0)
46. perror(“accept”);
47. write(newsockfd,msg,sizeof(msg));
48. is_connected[newsockfd] =1;
49. printf(“cnnect from %s\n”,inet_ntoa(addr.sin_addr));
50. }else{
51. bzero(buffer,sizeof(buffer));
52. if(read(fd,buffer,sizeof(buffer))<=0){
53. printf(“connect closed.\n”);
54. is_connected[fd]=0;
55. close(fd);
56. }else
57. printf(“%s”,buffer);
58. }
59. }
60. }
61. }

#include #include #include #include #include #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

执行 $ ./listen
connect from 127.0.0.1
hi I am client
connected closed.





13. ntohl(将32位网络字符顺序转换成主机字符顺序)
相关函数 htonl,htons,ntohs

表头文件 #include

定义函数 unsigned long int ntohl(unsigned long int netlong);

函数说明 ntohl()用来将参数指定的32位netlong转换成主机字符顺序。

返回值 返回对应的主机字符顺序。

范例 参考getservent()。





14. ntohs(将16位网络字符顺序转换成主机字符顺序)
相关函数 htonl,htons,ntohl

表头文件 #include

定义函数 unsigned short int ntohs(unsigned short int netshort);

函数说明 ntohs()用来将参数指定的16位netshort转换成主机字符顺序。

返回值 返回对应的主机顺序。

范例 参考getservent()。





15. recv(经socket接收数据)
相关函数 recvfrom,recvmsg,send,sendto,socket

表头文件 #include
#include

定义函数 int recv(int s,void *buf,int len,unsigned int flags);

函数说明 recv()用来接收远端主机经指定的socket传来的数据,并把数据存到由参数buf 指向的内存空间,参数len为可接收数据的最大长度。

参数 flags一般设0。其他数值定义如下:

* MSG_OOB 接收以out-of-band 送出的数据[*]MSG_PEEK 返回来的数据并不会在系统内删除,如果再调用recv()会返回相同的数据内容[*]MSG_WAITALL强迫接收到len大小的数据后才能返回,除非有错误或信号产生[*]MSG_NOSIGNAL此操作不愿被SIGPIPE信号中断返回值成功则返回接收到的字符数,失败返回-1,错误原因存于 errno中


错误代码

* EBADF 参数s非合法的socket处理代码[*]EFAULT 参数中有一指针指向无法存取的内存空间[*]ENOTSOCK 参数s为一文件描述词,非socket[*]EINTR 被信号所中断[*]EAGAIN 此动作会令进程阻断,但参数s的socket为不可阻断[*]ENOBUFS 系统的缓冲内存不足[*]ENOMEM 核心内存不足[*]EINVAL 传给系统调用的参数不正确


范例 参考listen()。





16. recvfrom(经socket接收数据)
相关函数 recv,recvmsg,send,sendto,socket

表头文件 #include
#include

定义函数 int recvfrom(int s,void *buf,int len,unsigned int flags ,struct sockaddr *from ,int *fromlen);

函数说明 recv ()用来接收远程主机经指定的socket 传来的数据,并把数据存到由参数buf 指向的内存空间,参数len 为可接收数据的最大长度。参数flags 一般设0,其他数值定义请参考recv()。参数from用来指定欲传送的网络地址,结构sockaddr 请参考bind()。参数fromlen为sockaddr的结构长度。

返回值 成功则返回接收到的字符数,失败则返回-1,错误原因存于errno中。

错误代码

* EBADF 参数s非合法的socket处理代码[*]EFAULT 参数中有一指针指向无法存取的内存空间[*]ENOTSOCK 参数s为一文件描述词,非socket[*]EINTR 被信号所中断[*]EAGAIN 此动作会令进程阻断,但参数s的socket为不可阻断[*]ENOBUFS 系统的缓冲内存不足[*]ENOMEM 核心内存不足[*]EINVAL 传给系统调用的参数不正确


范例
Cpp代码

1. /*利用socket的UDP client
2. 此程序会连线UDP server,并将键盘输入的字符串传给server。
3. UDP server 范例请参考sendto()
4. */
5. #include
6. #include
7. #include
8. #include
9. #include
10. #include
11. #include
12. #define PORT 2345
13. #define SERVER_IP “127.0.0.1”
14. main()
15. {
16. int s,len;
17. struct sockaddr_in addr;
18. int addr_len =sizeof(struct sockaddr_in);
19. char buffer[256];
20. /* 建立socket*/
21. if((s = socket(AF_INET,SOCK_DGRAM,0))<0){
22. perror(“socket”);
23. exit(1);
24. }
25. /* 填写sockaddr_in*/
26. bzero(&addr,sizeof(addr));
27. addr.sin_family = AF_INET;
28. addr.sin_port = htons(PORT);
29. addr.sin_addr.s_addr = inet_addr(SERVER_IP);
30. while(1){
31. bzero(buffer,sizeof(buffer));
32. /* 从标准输入设备取得字符串*/
33. len =read(STDIN_FILENO,buffer,sizeof(buffer));
34. /* 将字符串传送给server端*/
35. sendto(s,buffer,len,0,&addr,addr_len);
36. /* 接收server端返回的字符串*/
37. len = recvfrom(s,buffer,sizeof(buffer),0,&addr,&addr_len);
38. printf(“receive: %s”,buffer);
39. }
40. }

/*利用socket的UDP client 此程序会连线UDP server,并将键盘输入的字符串传给server。 UDP server 范例请参考sendto() */ #include #include #include #include #include #include #include #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)); /* 从标准输入设备取得字符串*/ 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); } }


执行 (先执行udp server 再执行udp client)
hello /*从键盘输入字符串*/
receive: hello /*server端返回来的字符串*/

回复主题
Copyright © 2008-2010 版权所属:中国Python联盟 www.okpython.com
京ICP备08012290号 村长QQ:81356625 E-mail:xieaotian@163.com