您的位置:首页 > 其它

综合使用套接字选项的例子,如设置套接字选项大小,设置套接字地址重用

2014-05-14 21:16 134 查看
1 #include <stdio.h>

2 #include <stdlib.h>

3 #include <sys/socket.h>

4 #include <signal.h>

5 #include <error.h>

6 #include <string.h>

7 #include <sys/types.h>

8 #include <netinet/in.h>

9 #include <sys/wait.h>

10 #include <arpa/inet.h>

11 #include <unistd.h>

12

13 #define PORT 8888 //服务器侦听端口为8888

14 #define BACKLOG 8 //最大侦听排队数量为8

15 static int alive=1; //是否退出

16

17 //用于处理SIGPIP和SIGINT信号的函数

18 static int signo(int signo)

19 {

20 alive=0;

21 }

22

23 int main(int argc,char* argv[])

24 {

25 //s为服务器的侦听套接字描述符,sc为客户端连接成功返回的描述符

26 int s,sc;

27 //local_addr本地地址,client_addr客户端的地址

28 struct sockaddr_in local_addr,client_addr;

29 int err=-1; //错误返回值

30 socket_t optlen=-1; //整型的选项类型值

31 int optval=-1; //选项类型长度

32 //截取SIGPIPE和SIGINT由函数signo处理

33 signal(SIGPIPE,signo);

34 signal(SIGINT,signo);

35

36 //创建本地监听套接字

37 s=socket(AF_INET,SOCK_STREAM,0);

38 if(s==-1)

39 {

40 printf("套接字创建失败!\n");

41 return -1;

42 }

43 //设置地址和端口重用

44 optval=1; //重用有效

45 optlen=sizeof(optval);

46 err=setsockopt(s,SOL_SOCKET,SO_REUSEADDR,(char*)&optval,optlen);

47 if(err!=-1)

48 {

49 printf("套接字可重用设置失败!\n");

50 return -1;

51 }

52

53 //初始化本地协议簇,端口和IP地址

54 bzero(&local_addr,0,sizeof(local_addr)); //清理

55 local_addr.sin_family=AF_INET; //协议簇

56 local_addr.sin_port=htons(PORT); //端口

57 local_addr.sin_addr.s_addr=INADDR_ANY; //任意本地地址

58 //绑定套接字

59 err=bind(s,(struct sockaddr*)&local_addr,sizeof(struct sockaddr));

60 if(err==-1)

61 {

62 printf("绑定失败!\n");

63 return -1;

64 }

65

66 //设置最大接收缓冲区和最大发送缓冲区

67 optval=128*1024; //缓冲区大小为128k

68 optlen=sizeof(optval);

69 err=setsockopt(s,SOL_SOCKET,SO_RCVBUF,&optval,optlen);

70 if(err==-1)

71 {

72 printf("设置接收缓冲区失败\n");

73 }

74 err=setsockopt(s,SOL_SOCKET,SO_SNDBUF,&optval,optlen);

75 if(err==-1)

76 {

77 printf("设置发送缓冲区失败\n");

78 }

79

80 //设置发送和接收超时时间

81 struct timeval tv;

82 tv.tv_sec=1;

83 tv.tv_usec=200000; //200ms

84 optlen=sizeof(tv);

85 err=setsockopt(s,SOL_SOCKET,SO_RCVTIMEO,&tv,optlen);

86 if(err==-1)

87 {

88 printf("设置接收超时时间失败\n");

89 }

90 err=setsockopt(s,SOL_SOCKET,SO_SNDTIMEO,&tv,optlen);

91 if(err==-1)

92 {

93 printf("设置发送超时时间失败\n");

94 }

95

96 //设置监听,监听队列长度为8

97 err=listen(s,BACKLOG);

98 if(err==-1)

99 {

100 printf("设置监听失败!\n");

101 return -1;

102 }

103

104 //设置accept超时时间

105 printf("等待连接...\n");

106 fd_set fd_r; //读文件描述符集合

107 tv.tv_sec=0;

108 tv.tv_usec=200000; //超时时间为200ms

109 while(alive)

110 {

111 //有连接请求时进行连接

112 socklen_t sin_size=sizeof(struct sockaddr_in);

113 //每次会轮询是否有客户端到来,间隔时间为200ms

114 FD_ZERO(&fd_r); //清除文件描述符集

115 FD_SET(s,&fd_r); //将侦听描述符放入

116 switch(select(s+1,&fd_r,NULL,&tv))

117 {

118 case -1: //错误发生

119 case 0: //超时

120 continue;

121 break;

122 default: //有连接到来

123 break;

124 }

125 //有连接到来,接收...

126 sc=accept(s,(struct sockaddr*)&client_addr,&sin_size);

127 if(sc==-1)

128 {

129 perror("接收连接失败!\n");

130 continue;

131 }

132 //设置连接探测超时时间

133 optval=10; //10s

134 optlen=sizeof(optval);

135 err=setsockopt(sc,IPPROTO_TCP,SO_KEEPALIVE,(char*)&optval,optlen);

136 if(err==-1)

137 {

138 printf("设置连接探测间隔时间失败\n");

139 }

140

141 //设置禁止Nagle算法

142 optval=1;

143 optlen=sizeof(optval);

144 err=setsockopt(sc,IPPROTO_TCP,TCP_NODELAY,(char*)&optval,optlen);

145 if(err==-1)

146 {

147 printf("禁止Nagle算法失败\n");

148 }

112 socklen_t sin_size=sizeof(struct sockaddr_in);

113 //每次会轮询是否有客户端到来,间隔时间为200ms

114 FD_ZERO(&fd_r); //清除文件描述符集

115 FD_SET(s,&fd_r); //将侦听描述符放入

116 switch(select(s+1,&fd_r,NULL,&tv))

117 {

118 case -1: //错误发生

119 case 0: //超时

120 continue;

121 break;

122 default: //有连接到来

123 break;

124 }

125 //有连接到来,接收...

126 sc=accept(s,(struct sockaddr*)&client_addr,&sin_size);

127 if(sc==-1)

128 {

129 perror("接收连接失败!\n");

130 continue;

131 }

132 //设置连接探测超时时间

133 optval=10; //10s

134 optlen=sizeof(optval);

135 err=setsockopt(sc,IPPROTO_TCP,SO_KEEPALIVE,(char*)&optval,optlen);

136 if(err==-1)

137 {

138 printf("设置连接探测间隔时间失败\n");

139 }

140

141 //设置禁止Nagle算法

142 optval=1;

143 optlen=sizeof(optval);

144 err=setsockopt(sc,IPPROTO_TCP,TCP_NODELAY,(char*)&optval,optlen);

145 if(err==-1)

146 {

147 printf("禁止Nagle算法失败\n");

148 }

149

150 //设置连接延迟关闭为立即关闭

151 struct linger linger;

152 linger.l_onoff=1; //延迟关闭生效

153 linger.l_linger=0; //立即关闭

154 optlen=sizeof(linger);

155 err=setsockopt(sc,SOL_SOCKET,SO_LINGER,(char*)&linger,optlen);

156 if(err==-1)

157 {

158 printf("设置立即关闭失败\n");

159 }

160

161 //打印客户端IP地址信息

162 printf("接到一个来自%s的连接\n",inet_ntoa(client_addr.sin_addr));

163 err=send(sc,"连接成功!\n",10,0);

164 if(err==-1)

165 {

166 printf("发送通知消息失败!\n");

167 }

168 //关闭客户端连接

169 close(sc);

170 }

171 //关闭服务器端

172 close(s);

173 return 0;

174 }
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: