안녕하세요 신사 숙녀 여러분, accept()
에 약간의 문제가 있습니다. 나는 여러 대의 클라이언트와 하나의 서버를 가지고있다. 클라이언트는 서버와 연결하여 통신 할 수 있습니다. 그러나 한순간에 나는 서로에게 직접적으로 연결되는 클라이언트가 필요하며 거기에는 약간의 어려움이 있습니다. 클라이언트는 계속되는 스레드를 가지고 있습니다. 그 중 하나는 handle_connection()
이고, 들어오는 연결은 listen()
과 accept()
으로 영원히 반복됩니다. while(1)
이 있습니다. 클라이언트가 connect()
다른 클라이언트에 시도 할 때마다 connect()
은 111 : Connection Refused라는 오류를 반환합니다. 올바른 IP 주소와 올바른 포트 (클라이언트 간 연결을 위해 포트를 지정했습니다)가 있음을 알고 있습니다. 연결을 기다리는 클라이언트는 새로운 연결이 없음을 알지 못합니다. 코드의 일부를 복사하여 누군가 내가 잘못하고있는 것을 지적 할 수 있기를 바랍니다. 모든 입력에 감사드립니다!C 소켓 : 클라이언트간에 connect() 및 accept()에 문제가 있습니다. 111 : Connection refused
이것은 모든 클라이언트 측 코드입니다. void * handle_connections(void * arg)
은 들어오는 연결을 언제나 accept()
으로 반복하는 스레드입니다. 내 서버는 매우 비슷한 thang을 가지고 있으며 매우 잘 작동합니다. (여기서 왜 작동하지 않는지 확실치 않습니다.) 이것은 새로운 들어오는 연결을 기다리는 클라이언트의 일부입니다. int handle_request(void * arg, struct message * msg)
은 프로그램 중 한 지점에서 호출되며 struct message * msg
에 지정된 클라이언트에 연결하려고 시도합니다.이 클라이언트에는 IP 주소와 포트 번호가 포함 된 struct sockaddr_in
이 포함됩니다.
#define SERVER_PORT 10000
#define CLIENT_PORT 3456
#define MAX_CONNECTION 20
#define MAX_MSG 50
void * handle_connections(void * arg)
{
struct fd_info * info;
struct sockaddr_in client_address;
struct timeval timeout;
fd_set readset, copyset;
bzero((char *) &client_address, sizeof(client_address)); // copy zeroes into string
client_address.sin_family = AF_INET;
client_address.sin_addr.s_addr = htonl(INADDR_ANY);
client_address.sin_port = htons(CLIENT_PORT);
sockfd = socket(AF_INET, SOCK_STREAM, 0);
rv = listen(sockfd,MAX_CONNECTION);
while(1)
{
new_sockfd = accept(sockfd, (struct sockaddr *) &client_address, &client_addr_len); //blocks
if (new_sockfd < 0) {
printf("C: ERROR accept() %i: %s \n", errno, strerror(errno));
sleep(2);
} else {
printf("C: accepted\n");
FD_SET(new_sockfd, &readset); // sets bit for new_sockfd to list of sockets to watch out for
if (maxfd < new_sockfd)
maxfd = new_sockfd;
if (minfd > new_sockfd)
minfd = new_sockfd;
} //end if else (new_sockfd)
} // end of the forever while loop
}
int handle_request(void * arg, struct message * msg)
{
char * cname, gname, payload;
char * command[3];
int i, rv, sockfd, client_addr_len;
struct sockaddr_in client_address;
struct fd_info * info;
info = (struct fd_info *) arg;
sockfd = info->sock_fd;
sockfd = socket(AF_INET, SOCK_STREAM, 0);
if (sockfd == -1)
{
printf("HR: ERROR socket() %i: %s \n", errno, strerror(errno));
break;
}
else if (sockfd > 0)
{
printf("HR: new socks is %i \n", sockfd);
printf("HR: sin_family is %i: %i\n", msg->peer.client_address.sin_family, msg->peer.client_address.sin_port);
//*************************************************************
//this is the part that returns error 111: Connection refused!!!
//*************************************************************
rv = connect(sockfd, (struct sockaddr *) &msg->peer.client_address, sizeof(struct sockaddr));
if (rv == -1)
{
printf("HR: ERROR: connect() %i: %s \n", errno, strerror(errno));
printf("HR: at %li \n", msg->peer.client_address.sin_addr.s_addr);
break;
}
else if (rv > 0)
{
info->max_fd = sockfd;
printf("HR: connected successfully!! \n");
}
}
}
고객이 방화벽을 사용하고 있습니까? –
오늘날 가정용 네트워크를위한 라우터는 점점 더 보편화되고 있습니다. 대부분의 라우터는 라우터 설정에서 명시 적으로 구성되지 않은 인바운드 트래픽이 통과하는 것을 방지합니다. 라우터를 사용하지 않더라도 개인 방화벽은 드문 일이 아닙니다. 어쨌든, 클라이언트가 NAT/방화벽 뒤에 있다면, 그 클라이언트는 보통 다른 클라이언트에 연결할 클라이언트 여야합니다. 따라서 NAT/방화벽은 인바운드 클라이언트가 아닌 아웃 바운드 연결을 보게됩니다. 두 클라이언트가 모두 NAT/방화벽 뒤에있는 경우 두 클라이언트가 아웃 바운드를 연결하도록 서버를 통해 데이터를 프록시해야합니다. –
글쎄, 클라이언트와 서버 모두 동일한 네트워크 내에 있지만 클라이언트는 서버에 잘 연결할 수 있습니다. 따라서 방화벽은 문제가되지 않을 것이라고 생각합니다. –