2012-07-16 120 views
7

我有一个数据采集模块,我想从中收集以太网端口的数据。 我在步骤到达那里,目前我只想从connect到客户端的服务器。我使用Beej的指南来获取基本的C代码。但是我只是不停收到这个连接错误connect: Connection refused.C,插座:连接拒绝错误

这是我做的:

  1. IP这里的网络是静态IP我已经配置。

  2. 的端口号设置为50000在服务器端和客户端我连接到该IP端口50000

  3. 我构建和运行服务器端的应用程序,然后尝试连接到它通过运行客户端应用程序。

一个关于服务器端,服务器端应用程序returns开始之前,我的客户端应用程序怀疑,所以我应该保持它运行(while(1);),这样我可以从客户端连接到它?

怎么回事我在这里忘了什么?帮帮我!

我粘贴了服务器端和客户端这里的非常轻微的修改(IP和端口号不同)Beej的C代码:

Server.c

/* 
** server.c 
*/ 
#include <stdio.h> 
#include <string.h> 
#include <sys/types.h> 
#include <sys/socket.h> 
#include <netdb.h> 
#include <arpa/inet.h> 
#include <netinet/in.h> 



int main(int argc, char *argv[]) 
{ 
    // code for a server waiting for connections 
    // namely a stream socket on port 3490, on this host's IP 
    // either IPv4 or IPv6. 
    int sockfd; 
    struct addrinfo hints, *servinfo, *p; 
    int rv; 
    memset(&hints, 0, sizeof hints); 
    hints.ai_family = AF_UNSPEC; // use AF_INET6 to force IPv6 
    hints.ai_socktype = SOCK_STREAM; 
    hints.ai_flags = AI_PASSIVE; // use my IP address 

    if ((rv = getaddrinfo(NULL, "50000", &hints, &servinfo)) != 0) 
    { 
     fprintf(stderr, "getaddrinfo: %s\n", gai_strerror(rv)); 
     exit(1); 
    } 

    // loop through all the results and bind to the first we can 
    for(p = servinfo; p != NULL; p = p->ai_next) 
    { 
     if ((sockfd = socket(p->ai_family, p->ai_socktype, 
     p->ai_protocol)) == -1) 
     { 
      perror("socket"); 
      continue; 
     } 
     if (bind(sockfd, p->ai_addr, p->ai_addrlen) == -1) 
     { 
      close(sockfd); 
      perror("bind"); 
      continue; 
     } 
     break; // if we get here, we must have connected successfully 
    } 

    if (p == NULL) 
    { 
     // looped off the end of the list with no successful bind 
     fprintf(stderr, "failed to bind socket\n"); 
     exit(2); 
    } 

    freeaddrinfo(servinfo); // all done with this structure 

} 

Client.c

/* 
** client.c 
*/ 
#include <stdio.h> 
#include <string.h> 
#include <sys/types.h> 
#include <sys/socket.h> 
#include <netdb.h> 
#include <arpa/inet.h> 
#include <netinet/in.h> 

int main(int argc, char *argv[]) 
{ 
    // code for a client connecting to a server 
    // namely a stream socket to www.example.com on port 80 (http) 
    // either IPv4 or IPv6 
    int sockfd; 
    struct addrinfo hints, *servinfo, *p; 
    int rv; 
    memset(&hints, 0, sizeof hints); 
    hints.ai_family = AF_UNSPEC; // use AF_INET6 to force IPv6 
    hints.ai_socktype = SOCK_STREAM; 
    if ((rv = getaddrinfo("192.168.2.4", "50000", &hints, &servinfo)) != 0) 
    { 
     fprintf(stderr, "getaddrinfo: %s\n", gai_strerror(rv)); 
     exit(1); 
    } 
    // loop through all the results and connect to the first we can 
    for(p = servinfo; p != NULL; p = p->ai_next) 
    { 
     if ((sockfd = socket(p->ai_family, p->ai_socktype, 
     p->ai_protocol)) == -1) 
     { 
      perror("socket"); 

     continue; 
     } 
     if (connect(sockfd, p->ai_addr, p->ai_addrlen) == -1) 
     { 
      close(sockfd); 
      perror("connect"); 
      continue; 
     } 
     break; // if we get here, we must have connected successfully 
    } 

    if (p == NULL) 
    { 
     // looped off the end of the list with no connection 
     fprintf(stderr, "failed to connect\n"); 
     exit(2); 
    } 

    freeaddrinfo(servinfo); // all done with this structure 

} 

回答

6

您的发球r代码丢失listen()accept()代码通过调用listen()来“等待”连接,然后执行accept()来接受新的连接。你正在使用的示例没有演示如何做到这一点?通常,您还将为每个新连接分配一个新线程。

有关更多信息,请参见http://www.linuxhowtos.org/C_C++/socket.htm

这里有一个链接到一个更完整的实现:http://www.thegeekstuff.com/2011/12/c-socket-programming/

+0

谢谢你的链接,他们是一个很好的阅读。 – HaggarTheHorrible 2012-07-16 03:38:08

+0

@HeatfanJohn我检查了这些代码,但结果相同的问题。[server.c](https://paste.ubuntu.com/25599389/)[client.c](https://paste.ubuntu。 com/25599391 /) – alhelal 2017-09-23 13:40:30

+0

@BandaMuhammadAlHelal当您的客户端尝试连接到端口FTP_PORT(21)时,您的服务器似乎在端口9999上侦听。更改您的客户端以使用端口9999连接到。 – HeatfanJohn 2017-09-25 17:14:24

1

请看看你的Server.c文件:它不叫听()在所有!
如果目标服务器不侦听指定的端口,那么它将在收到来自客户端的SYN数据包时返回RST数据包,因此connect()将返回“Connection refused”。在服务器端的功能

正常流动是插座 - >绑定 - >听 - >接受:

getaddrinfo(); 
socket(); 
bind(); 
listen(); 
/* accept() goes here */ 

请参考http://beej.us/guide/bgnet/output/html/multipage/syscalls.html#listen

3

是的,你需要保持运行服务器程序。在您的服务器程序中,您使用socket()创建了套接字并绑定到地址bind(),现在您需要开始监听传入连接。这是通过listen()调用完成的。一旦套接字正在监听传入连接,您必须使用accept()调用来实际接受连接并获取与该特定客户端进行通信的套接字。

作为一个简单的例子,以后freeaddrinfo您可以添加以下代码:

listen(sockfd, 8); /* allow up to 8 pending connections, i.e. created but not accepted */ 
while (1) { 
    int clientfd; 
    struct sockaddr_in client_addr; 
    socklen_t client_addr_len = sizeof(struct sockaddr_in); 
    clientfd = accept(sockfd, &client_addr, &client_addr_len); 
    /* communicate with client by send()/recv() or write()/read() on clientfd */ 
    close(clientfd); 
} 

这段代码有一次只有一个客户端处理的不足。有几种方法可以处理多个同时发生的客户端:使用fork(),多个线程或轮询的多个进程。在我看来,这些方法都不在这个问题的范围之内。

0

由于没有在/ etc/hosts文件中输入远程主机,我得到错误“连接被拒绝”。入场应该在双方中出现。在客户端机器/ etc/hosts中,应该有一个服务器机器的条目,反之亦然。

<ip address> <hostname with domain> <alias hostname>

这解决了我在的getaddrinfo()函数的错误。