我如何使用的setsockopt(SO_REUSEADDR)? [英] How do I use setsockopt(SO_REUSEADDR)?

查看:264
本文介绍了我如何使用的setsockopt(SO_REUSEADDR)?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我运行一个树莓派我自己的HTTP服务器。问题是,当我停止该程序并重新启动,端口不再可用。有时候,我收到大量请求时,得到了同样的问题。结果
我想用SO_REUSEADDR,这样我可以继续使用,甚至当错误发生时,但有没有运气得到它设置的端口。下面是我的code。结果
我得到的错误是错误的绑定:地址已在使用。

 的#include<&stdio.h中GT;
#包括LT&;&stdlib.h中GT;
#包括LT&;&string.h中GT;
#包括LT&;&unistd.h中GT;
#包括LT&; SYS / types.h中>
#包括LT&; SYS / socket.h中>
#包括LT&; netinet / in.h中>无效错误(为const char * MSG)
{
    PERROR(MSG);
    出口(1);
}INT主(INT ARGC,CHAR *的argv [])
{
    的printf(启动监听\\ n);
     INT的sockfd,newsockfd,PORTNO;
     socklen_t的clilen;
     字符缓冲区[256];
     结构SOCKADDR_IN serv_addr,cli_addr;
     INT N;
     如果(的argc 2){
         fprintf中(标准错误,错误,没有端口提供\\ n);
         出口(1);
     }
     的sockfd =插座(AF_INET,SOCK_STREAM,0);
     如果(的sockfd℃,)
        错误(错误打开插座);
     bzero((字符*)及serv_addr,sizeof的(serv_addr));
     PORTNO =的atoi(ARGV [1]);
     serv_addr.sin_family = AF_INET;
     serv_addr.sin_addr.s_addr = INADDR_ANY;
     serv_addr.sin_port = htons(PORTNO);
     如果(绑定(的sockfd,(结构sockaddr *)及serv_addr,
              的sizeof(serv_addr))≤; 0)
              错误(绑定错误);     的printf(要听\\ n);
     听(的sockfd,5);
     的printf(听完\\ n);
     clilen = sizeof的(cli_addr);
     的printf(关于接受\\ n);     INT I;
     对于(i = 0; I< 100;我++){
         newsockfd =接受(的sockfd,
                 (结构sockaddr *)及cli_addr,
                 &安培; clilen);         如果(newsockfd℃,)
             错误(ERROR在接受);
         bzero(缓冲液,256);
         N =读(newsockfd,缓冲器,255);
         如果(N小于0)错误(ERROR从套接字读取);
         的printf(这是消息:%S \\ n,缓冲区);
         N =写(newsockfd,我收到了你的信息,18);
         如果(N小于0)错误(写入插座);
         关闭(newsockfd);
     }
     接近(的sockfd);
     返回0;
}


解决方案

  =的sockfd插座(AF_INET,SOCK_STREAM,0);
如果(的sockfd℃,)
    错误(错误打开插座);

您可以添加(与标准C99复合litteral支持):

 如果(setsockopt的(的sockfd,SOL_SOCKET,SO_REUSEADDR,及(INT){1}的sizeof(int)的)℃下)
    错误(setsockopt的(SO_REUSEADDR)失败);

或者

  INT启用= 1;
如果(setsockopt的(的sockfd,SOL_SOCKET,SO_REUSEADDR,&安培;启用的sizeof(int)的)℃下)
    错误(setsockopt的(SO_REUSEADDR)失败);

I am running my own http server on a raspberry pi. The problem is when I stop the program and restart it, the port is no longer available. Sometimes I get the same issue when receiving lots of requests.
I want to use SO_REUSEADDR so that I can keep using the port even when the error occurs but have had no luck getting it set up. Below is my code.
The error I get is "ERROR on binding:Address already in use".

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h> 
#include <sys/socket.h>
#include <netinet/in.h>

void error(const char *msg)
{
    perror(msg);
    exit(1);
}

int main(int argc, char *argv[])
{
    printf("Starting Listener\n");
     int sockfd, newsockfd, portno;
     socklen_t clilen;
     char buffer[256];
     struct sockaddr_in serv_addr, cli_addr;
     int n;
     if (argc < 2) {
         fprintf(stderr,"ERROR, no port provided\n");
         exit(1);
     }
     sockfd = socket(AF_INET, SOCK_STREAM, 0);
     if (sockfd < 0) 
        error("ERROR opening socket");
     bzero((char *) &serv_addr, sizeof(serv_addr));
     portno = atoi(argv[1]);
     serv_addr.sin_family = AF_INET;
     serv_addr.sin_addr.s_addr = INADDR_ANY;
     serv_addr.sin_port = htons(portno);
     if (bind(sockfd, (struct sockaddr *) &serv_addr,
              sizeof(serv_addr)) < 0) 
              error("ERROR on binding");

     printf("about to listen\n");
     listen(sockfd,5);
     printf("finished listening\n");
     clilen = sizeof(cli_addr);
     printf("About to accept\n");

     int i;
     for(i=0; i<100; i++){
         newsockfd = accept(sockfd, 
                 (struct sockaddr *) &cli_addr, 
                 &clilen);

         if (newsockfd < 0) 
             error("ERROR on accept");
         bzero(buffer,256);
         n = read(newsockfd,buffer,255);
         if (n < 0) error("ERROR reading from socket");
         printf("Here is the message: %s\n",buffer);
         n = write(newsockfd,"I got your message",18);
         if (n < 0) error("ERROR writing to socket");
         close(newsockfd);
     }
     close(sockfd);
     return 0; 
}

解决方案

After :

sockfd = socket(AF_INET, SOCK_STREAM, 0);
if (sockfd < 0) 
    error("ERROR opening socket");

You can add (with standard C99 compound litteral support) :

if (setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, &(int){ 1 }, sizeof(int)) < 0)
    error("setsockopt(SO_REUSEADDR) failed");

Or :

int enable = 1;
if (setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, &enable, sizeof(int)) < 0)
    error("setsockopt(SO_REUSEADDR) failed");

这篇关于我如何使用的setsockopt(SO_REUSEADDR)?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆