- 论坛徽章:
- 0
|
碰到一个自己解释不通的问题,大家看看怎么解释:
客户端代码:- int main(int argc, char* argv[]){
- int ilRet = 0;
- while(1){
- struct sockaddr_in slAddr;
- bzero(&slAddr, sizeof(slAddr));
- slAddr.sin_family = AF_INET;
- slAddr.sin_port = htons(44445);
- slAddr.sin_addr.s_addr = inet_addr("172.17.236.122");
- int sockfd = socket(AF_INET, SOCK_STREAM, 0);
- if (-1 == sockfd) {
- printf("socket()fail, errno[%d], errmsg[%s]\n", errno, strerror(errno));
- return -1;
- }
- printf("socket ok!\n");
- /*const int on = 1;
- if (setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on)) == -1 ) {
- printf("setsockopt sockfd[%d] fail, errno[%d], errmsg[%s]\n",
- sockfd, errno,strerror(errno));
- return -1;
- }
- printf("setsockopt ok!\n");*/
- printf("connect!\n");
- unsigned int len = sizeof(slAddr);
- if (connect(sockfd, (struct sockaddr*)&slAddr, len) == 0){
- printf("connect ok!\n");
- sleep(10000000);
- char buf[100];
- if(recv(sockfd,buf, 100, 0) <= 0){
- printf("recv error!\n");
- close(sockfd);
- continue;
- }
- break;
- }
- else{
- printf("connect fail, errno[%d], errmsg[%s]\n", errno, strerror(errno));
- }
- sleep(1);
- }
- }
复制代码 服务器代码:- int main(int argc, char* argv[]){
- int ilRet = 0;
- int fd = 0;
- struct sockaddr_in slAddr;
- bzero(&slAddr, sizeof(slAddr));
- slAddr.sin_family = AF_INET;
- slAddr.sin_port = htons(51365);
- //slAddr.sin_addr.s_addr = htonl(INADDR_ANY);
- slAddr.sin_addr.s_addr = inet_addr("172.18.64.64");
- /* inet_pton(AF_INET, paIP, &slAddr.sin_addr); */
- struct sockaddr_in pAddr;
- bzero(&pAddr, sizeof(pAddr));
- int sockfd = socket(AF_INET, SOCK_STREAM, 0);
- if (-1 == sockfd) {
- printf("socket()fail, errno[%d], errmsg[%s]\n", errno, strerror(errno));
- return -1;
- }
- printf("socket ok!\n");
- int on = 1;
- if (setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on)) != 0 ) {
- printf("setsockopt sockfd[%d] fail, errno[%d], errmsg[%s]\n",
- sockfd, errno,strerror(errno));
- return -1;
- }
- printf("setsockopt ok!\n");
- if (bind(sockfd, (struct sockaddr *)&slAddr, sizeof(slAddr)) != 0) {
- printf("bind()sockfd[%d]fail, errno[%d], errmsg[%s]\n",
- sockfd, errno,strerror(errno));
- close(sockfd);
- return -1;
- }
- printf("bind ok!\n");
- if (listen(sockfd, 5) != 0) {
- close(sockfd);
- printf("listen fail, errno[%d], errmsg[%s]\n", errno,strerror(errno));
- return -1;
- }
- printf("listen ok!\n");
- /*后面省略1000字*/
复制代码 服务器端监听端口填写成客户端的随机端口,在客户端启动的机器上(同一台机器)启动服务端
报错:
socket ok!
setsockopt ok!
bind()sockfd[3]fail, errno[98], errmsg[Address already in use]
再次修改客户端的代码,将客户端代码中
setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on)的注释打开,重新启动客户端和服务端程序,服务端正常监听:
socket ok!
setsockopt ok!
bind ok!
listen ok!
netstat -an |grep 51365
tcp 0 0 172.18.64.64:51365 0.0.0.0:* LISTEN
tcp 0 0 172.18.64.64:51365 172.17.236.122:44445 ESTABLISHED
系统版本信息:
cat /etc/issue
Welcome to SUSE Linux Enterprise Server 11 SP2 (x86_64) - Kernel \r (\l).
lsb_release -a
LSB Version: core-2.0-noarch:core-3.2-noarch:core-4.0-noarch:core-2.0-x86_64:core-3.2-x86_64:core-4.0-x86_64:desktop-4.0-amd64:desktop-4.0-noarch:graphics-2.0-amd64:graphics-2.0-noarch:graphics-3.2-amd64:graphics-3.2-noarch:graphics-4.0-amd64:graphics-4.0-noarch
Distributor ID: SUSE LINUX
Description: SUSE Linux Enterprise Server 11 (x86_64)
Release: 11
Codename: n/a
不解的问题:
1、随机端口被占用,比如说45000,那么在45000上的监听就起不来么?那这么说所有的监听端口是不是都要在随机端口的范围下面才合适?有书上这么说么,比如说UNP或者TCP/IP详解,没见到。。
2、SO_REUSEADDR我所理解就是解决服务端TIME_WAIT的问题(大部分应用都是这么用的),今天的这个例子怎么解释,用UNP里面SO_REUSEADDR应用说明的四条中的那一条解释合适?
球大侠现身。。。 |
|