localhost上的服务器看不到接受连接

时间:2017-07-11 23:37:15

标签: c sockets tcp server localhost

//serv.c
#include <stdlib.h>
#include <unistd.h>
#include <stdio.h>
#include <getopt.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <string.h>
#include <netinet/in.h>
#include <netdb.h>
#include <poll.h>
#include <signal.h>
#include <string.h>
#include <sys/wait.h>
int main(int argc, char *argv[])
{

    FILE *log;
    int port_no;
    struct sockaddr_in server_addr;
    struct hostent* server;    int port_flag=0;
    int c;
    while(1)
    {
        static struct option long_options[]=
        {
            {"port",required_argument,0,'p'},
            {"log",required_argument,0,'l'},
        };
        c= getopt_long(argc,argv,"p:l",long_options,NULL);
        if(c==-1)
            break;
        switch(c)
        {
            case 'l':
                if(optarg)
                {
                    if(optarg[0]!='-')
                    {
                        log= fopen(optarg,"w");
                    }
                    else
                    {
                        fprintf(stderr,"log requires argument\n");
                    }

                }
                break;
            case 'p':
                if(optarg)
                {
                    if(optarg[0]!='-')
                    {
                        port_no= atoi(optarg);
                        port_flag=1;
                    }
                    else{
                        printf("Usage --port=PORT_NUMBER\n");
                    }
                }
                else
                {
                    printf("Usage --port=PORT_NUMBER\n");
                }
                break;
            case '?':
                write(STDOUT_FILENO,"\r",1);
                exit(1);
                break;
            default:
                break;

        }

    }

int opt = 0, port_num, client_len;
    struct sockaddr_in server_addr, client_addr;
    socket_fd = socket(AF_INET, SOCK_STREAM, 0);
    if(socket_fd < 0) { perror("Error opening socket"); exit(1); }
    memset((char*) &server_addr, 0, sizeof(server_addr));
    server_addr.sin_family = AF_INET;
    server_addr.sin_port = htons(port_num);
    server_addr.sin_addr.s_addr = INADDR_ANY;
    if(bind(socket_fd, (struct sockaddr *) &server_addr, sizeof(server_addr)) < 0)
    {
        perror("Error binding socket");
        exit(1);
    }
    listen(socket_fd,5);
    client_len=sizeof(client_addr);
    newsocket_fd=accept(socket_fd,(struct sockaddr *)&client_addr,&client_len);
    printf("accepting");
    if(newsocket_fd<0)
    {
        fprintf(stderr,"error on accept");

    }
    char buffer[256];
    memset(buffer,0,256);
    int n=read(newsocket_fd,buffer,255);
    if(n<0)
    {
        fprintf(stderr,"Error reading from socket");

    }
    printf("Here is the message: %s\n",buffer);
    n=write(newsocket_fd,"I got your message",18);
}

client.c

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

    FILE *log;
    int port_no;
    struct sockaddr_in server_addr;
    struct hostent* server;    int port_flag=0;
    int c;
    while(1)
    {
        static struct option long_options[]=
        {
            {"port",required_argument,0,'p'},
            {"log",required_argument,0,'l'},
        };
        c= getopt_long(argc,argv,"p:l",long_options,NULL);
        if(c==-1)
            break;
        switch(c)
        {
            case 'l':
                if(optarg)
                {
                    if(optarg[0]!='-')
                    {
                        log= fopen(optarg,"w");
                    }
                    else
                    {
                        fprintf(stderr,"log requires argument\n");
                    }

                }
                break;
            case 'p':
                if(optarg)
                {
                    if(optarg[0]!='-')
                    {
                        port_no= atoi(optarg);
                        port_flag=1;
                    }
                    else{
                        printf("Usage --port=PORT_NUMBER\n");
                    }
                }
                else
                {
                    printf("Usage --port=PORT_NUMBER\n");
                }
                break;
            case '?':
                write(STDOUT_FILENO,"\r",1);
                exit(1);
                break;
            default:
                break;

        }

    }
    char buffer[256];
            socket_fd = socket(AF_INET, SOCK_STREAM, 0);
            if(socket_fd < 0) { perror("Error opening socket"); exit(0); }
            server = gethostbyname("localhost");
            if(server == NULL) { fprintf(stderr, "Cannot find host"); exit(0); }
            //Initialize the server address to zero and then correctly assign it
            memset((char*) &server_addr,0, sizeof(server_addr));
            server_addr.sin_family = AF_INET;
            memcpy((char *) &server_addr.sin_addr.s_addr,
                   (char*) server->h_addr,
                   server->h_length);
            server_addr.sin_port = htons(port_no);


if(connect(socket_fd,(struct sockaddr *) &server_addr, sizeof(server_addr)) < 0) { perror("Error connecting"); exit(0); }
        printf("Please enter the message");
        memset(buffer,0,256);
        fgets(buffer,255,stdin);
        int n=write(socket_fd,buffer,strlen(buffer));
        if(n<0)
        {
            fprintf(stderr,"error writing to socket");
        }
        memset(buffer,0,256);
        n=read(socket_fd,buffer,255);
        if(n<0)
        {
            printf("Error reading");
        }
        printf("%s\n",buffer);}

}

我不知道为什么,但服务器似乎不接受套接字 来自客户的连接。我尝试过超过1024的端口号。只是 不起作用。端口号是用户输入的。是否只有port_no可用于它?

2 个答案:

答案 0 :(得分:1)

您发布的“完整代码”未完整,因为它无法编译(提示:client.c不包含单个头文件)。通过简单的修复,一个重要的线索来自编译并启用警告:

$ gcc -g serv.c -o serv -Wall -Wextra
serv.c: In function 'main':
serv.c:94:71: warning: pointer targets in passing argument 3 of 'accept' differ in signedness [-Wpointer-sign]
     int newsocket_fd=accept(socket_fd,(struct sockaddr *)&client_addr,&client_len);
                                                                       ^
In file included from serv.c:7:0:
/usr/include/x86_64-linux-gnu/sys/socket.h:243:12: note: expected 'socklen_t * __restrict__' but argument is of type 'int *'
 extern int accept (int __fd, __SOCKADDR_ARG __addr,
            ^
serv.c:79:5: warning: unused variable 'opt' [-Wunused-variable]
 int opt = 0, port_num, client_len;
     ^
serv.c:23:36: warning: variable 'port_flag' set but not used [-Wunused-but-set-variable]
     struct hostent* server;    int port_flag=0;
                                    ^
serv.c:23:21: warning: unused variable 'server' [-Wunused-variable]
     struct hostent* server;    int port_flag=0;
                     ^
serv.c:21:9: warning: variable 'port_no' set but not used [-Wunused-but-set-variable]
     int port_no;
         ^
serv.c:20:11: warning: variable 'log' set but not used [-Wunused-but-set-variable]
     FILE *log;
           ^
serv.c:111:1: warning: control reaches end of non-void function [-Wreturn-type]
 }
 ^
serv.c:85:28: warning: 'port_num' may be used uninitialized in this function [-Wmaybe-uninitialized]
     server_addr.sin_port = htons(port_num);

看看最后一次警告 - “port_num”未初始化?再看一下:“port_no”已初始化但未使用?因此,参数处理是徒劳的,你正在监听任意端口 - 检查@Pras的“netstat -l -p”的建议也会显示出来。

作为一种调试策略,值得用迂腐警告进行编译(并尝试使用像clang这样的更多诊断编译器)来寻找线索。作为一种常见的开发策略,通过始终启用警告并在运行代码之前修复它们来减少调试时间。

答案 1 :(得分:0)

因为您在这里询问服务器是我注意到的。

两者&#34; port_no&#34;和&#34; port_num&#34;声明,用户输入它分配给&#34; port_no&#34;但你正在使用&#34; port_num&#34;当调用htons()时。

您的切换案例后重新声明'server_addr',并且还缺少newsocket_fd

$gcc -o server server.c 
server.c: In function ‘main’:
server.c:80:24: error: redeclaration of ‘server_addr’ with no linkage
     struct sockaddr_in server_addr, client_addr;
                        ^~~~~~~~~~~
server.c:22:24: note: previous declaration of ‘server_addr’ was here
     struct sockaddr_in server_addr;
                        ^~~~~~~~~~~
server.c:81:5: error: ‘socket_fd’ undeclared (first use in this function)
     socket_fd = socket(AF_INET, SOCK_STREAM, 0);
     ^~~~~~~~~
server.c:81:5: note: each undeclared identifier is reported only once for each function it appears in
server.c:94:5: error: ‘newsocket_fd’ undeclared (first use in this function)
     newsocket_fd=accept(socket_fd,(struct sockaddr *)&client_addr,&client_len);

无论哪种方式,我移除了开关盒并手动分配了端口号以使其运行,您需要检查输入并清除一些错误,但这是一个代码的工作示例,其中包含有关更改的注释。 / p>

我使用netcat作为客户端来测试连接。

$ netcat 127.0.0.1 5555
test message
I got your message 

输出代码与您提供的内容没有变化,这是它将显示的内容。使用&#34; \ n&#34;换行。

$gcc -o server server.c 
example@pc:~$./server
acceptingHere is the message: test message

以下是修改后的代码:

//serv.c
#include <stdlib.h>
#include <unistd.h>
#include <stdio.h>
#include <getopt.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <string.h>
#include <netinet/in.h>
#include <netdb.h>
#include <poll.h>
#include <signal.h>
#include <string.h>
#include <sys/wait.h>
int main(int argc, char *argv[])
{

    FILE *log;
    // Added socket_fd and newsocket_fd
    int socket_fd, newsocket_fd;
    // use uint16_t for port number    
    uint16_t port_no;
    //Removed struct sockaddr_in server_addr;
    struct hostent* server;    int port_flag=0;
    int c;

    port_no = 5555;
    /* removed switch to show server does function
    while(1)
    {
        static struct option long_options[]=
        {
            {"port",required_argument,0,'p'},
            {"log",required_argument,0,'l'},
        };
        c= getopt_long(argc,argv,"p:l",long_options,NULL);
        if(c==-1)
            break;
        switch(c)
        {
            case 'l':
                if(optarg)
                {
                    if(optarg[0]!='-')
                    {
                        log= fopen(optarg,"w");
                    }
                    else
                    {
                        fprintf(stderr,"log requires argument\n");
                    }

                }
                break;
            case 'p':
                if(optarg)
                {
                    if(optarg[0]!='-')
                    {
                        port_no= atoi(optarg);
                        port_flag=1;
                    }
                    else{
                        printf("Usage --port=PORT_NUMBER\n");
                    }
                }
                else
                {
                    printf("Usage --port=PORT_NUMBER\n");
                }
                break;
            case '?':
                write(STDOUT_FILENO,"\r",1);
                exit(1);
                break;
            default:
                break;

        }

    }
    */

    // Removed port_num
    int opt = 0, client_len;
    struct sockaddr_in server_addr, client_addr;
    socket_fd = socket(AF_INET, SOCK_STREAM, 0);
    if(socket_fd < 0) { perror("Error opening socket"); exit(1); }
    memset((char*) &server_addr, 0, sizeof(server_addr));
    server_addr.sin_family = AF_INET;
    // using port_no in htons
    server_addr.sin_port = htons(port_no);
    server_addr.sin_addr.s_addr = INADDR_ANY;
    if(bind(socket_fd, (struct sockaddr *) &server_addr, sizeof(server_addr)) < 0)
    {
        perror("Error binding socket");
        exit(1);
    }
    listen(socket_fd,5);
    client_len=sizeof(client_addr);
    newsocket_fd=accept(socket_fd,(struct sockaddr *)&client_addr,&client_len);
    printf("accepting");
    if(newsocket_fd<0)
    {
        fprintf(stderr,"error on accept");

    }
    char buffer[256];
    memset(buffer,0,256);
    int n=read(newsocket_fd,buffer,255);
    if(n<0)
    {
        fprintf(stderr,"Error reading from socket");

    }
    printf("Here is the message: %s\n",buffer);
    n=write(newsocket_fd,"I got your message",18);
}