Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/61.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
关于C(Linux)中socket服务器客户端编程中accept()的问题_C_Linux_Sockets_Network Programming_Client Server - Fatal编程技术网

关于C(Linux)中socket服务器客户端编程中accept()的问题

关于C(Linux)中socket服务器客户端编程中accept()的问题,c,linux,sockets,network-programming,client-server,C,Linux,Sockets,Network Programming,Client Server,我在Linux中用C语言编写了一个服务器和客户端程序 代码如下: 服务器代码: #include<stdio.h> #include<string.h> //strlen #include<sys/socket.h> #include<arpa/inet.h> //inet_addr #include<unistd.h> //write int main(int argc , char *argv[]) { int soc

我在Linux中用C语言编写了一个服务器和客户端程序

代码如下:

服务器代码:

#include<stdio.h>
#include<string.h>    //strlen
#include<sys/socket.h>
#include<arpa/inet.h> //inet_addr
#include<unistd.h>    //write

int main(int argc , char *argv[])
{
int socket_desc , client_sock , c , read_size;
struct sockaddr_in server , client;
char client_message[2000];

//Create socket
socket_desc = socket(AF_INET , SOCK_STREAM , 0);
if (socket_desc == -1)
{
    printf("Could not create socket");
}
puts("Socket created");

//Prepare the sockaddr_in structure
server.sin_family = AF_INET;
server.sin_addr.s_addr = INADDR_ANY;
server.sin_port = htons( 8888 );

//Bind
if( bind(socket_desc,(struct sockaddr *)&server , sizeof(server)) < 0)
{
    //print the error message
    perror("bind failed. Error");
    return 1;
}
puts("bind done");

//Listen
listen(socket_desc , 3);

//Accept and incoming connection
puts("Waiting for incoming connections...");
c = sizeof(struct sockaddr_in);

//accept connection from an incoming client
client_sock = accept(socket_desc, (struct sockaddr *)&client, (socklen_t*)&c);
if (client_sock < 0)
{
    perror("accept failed");
    return 1;
 }
puts("Connection accepted");
  close(client_sock);
  puts("I am at While loop");
  while(1)
    {
    }
return 0;
}
客户端输出:

root@beaglebone:/home/Saad/test# ./client_test     
Socket created                         
Connected                                                           

^C                                                   
root@beaglebone:/home/Saad/test# ./client_test
Socket created                                              
Connected          
我不知道为什么会发生这种情况以及如何解决它

更新:

在对客户端代码进行了一些编辑之后,我尝试了下面的答案。我面临着同样的问题

客户端代码:

#include<stdio.h> //printf
#include<string.h>    //strlen
#include<sys/socket.h>    //socket
#include<arpa/inet.h> //inet_addr

int main(int argc , char *argv[])
{
   char buf[1];
int sock;
struct sockaddr_in server;
char message[1000] , server_reply[2000];
int ret;

//Create socket
sock = socket(AF_INET , SOCK_STREAM , 0);
if (sock == -1)
{
    printf("Could not create socket");
}
puts("Socket created");

server.sin_addr.s_addr = inet_addr("192.168.1.2");
server.sin_family = AF_INET;
server.sin_port = htons( 8888 );

//Connect to remote server
ret = connect(sock , (struct sockaddr *)&server , sizeof(server));
if (ret < 0)
{
    perror("connect failed. Error");
    return 1;
}
recv(sock, buf, 1, MSG_WAITFORONE);
printf("%s",buf);
puts("Connected\n");
close(sock);
sock = socket(AF_INET , SOCK_STREAM , 0);
if (sock == -1)
{
    printf("Could not create socket");
}
puts("Socket created");
ret = connect(sock , (struct sockaddr *)&server , sizeof(server));
if (ret < 0)
{
    perror("connect failed. Error");
    return 1;
}
else
{
 puts("Connected\n");
}
while(1);
return 0;
}
我不希望客户端连接,直到服务器调用accept()与客户端连接

运气不好,TCP不是这样工作的
listen(socket_desc,3)
创建一个待办事项队列,使用第二个参数作为其长度的提示,在本例中,该参数将被忽略,因为它太小。此队列的目的是保存TCP已完成但服务器应用程序尚未接受的连接。根据平台的不同,典型尺寸从50到500或更多不等

我只想让客户端等待或超时,直到服务器调用
accept()
在它们之间建立连接

不可实现的。你为什么认为你需要这个

我不知道为什么会发生这种情况以及如何解决它


您无法解决它,除非按照@IshayPeled的回答通过无意义的额外发送/接收。这不是一个需要解决的问题。如果你不这么认为,请告诉我们原因。其他所有编写的TCP应用程序都是这样工作的。您的有什么不同吗?

@EJP解释得很好,如果您想解决问题,请使用以下代码:

客户:

#include<stdio.h> //printf
#include<string.h>    //strlen
#include<sys/socket.h>    //socket
#include<arpa/inet.h> //inet_addr

int main(int argc , char *argv[])
{
    char buf[1];
    int sock;
    struct sockaddr_in server;
    char message[1000] , server_reply[2000];
    int ret;

    //Create socket
    sock = socket(AF_INET , SOCK_STREAM , 0);
    if (sock == -1)
    {
        printf("Could not create socket");
    }
    puts("Socket created");

    server.sin_addr.s_addr = inet_addr("127.0.0.1");
    server.sin_family = AF_INET;
    server.sin_port = htons( 8888 );

    //Connect to remote server
    ret = connect(sock , (struct sockaddr *)&server , sizeof(server));
    if (ret < 0)
    {
        perror("connect failed. Error");
        return 1;
    }
    recv(sock, buf, 1, MSG_WAITFORONE);

    puts("Connected\n");
    close(sock);
    while(1);
    return 0;
}
#包括//printf
#包括//strlen
#包含//套接字
#包括//inet\u addr
int main(int argc,char*argv[])
{
char-buf[1];
int袜子;
服务器中的结构sockaddr_;
字符消息[1000],服务器回复[2000];
int ret;
//创建套接字
sock=socket(AF\u INET,sock\u STREAM,0);
如果(sock==-1)
{
printf(“无法创建套接字”);
}
放置(“已创建套接字”);
server.sin_addr.s_addr=inet_addr(“127.0.0.1”);
server.sinu family=AF\u INET;
server.sin_port=htons(8888);
//连接到远程服务器
ret=connect(sock,(struct sockaddr*)&server,sizeof(server));
如果(ret<0)
{
perror(“连接失败。错误”);
返回1;
}
recv(短袜、布袋、1号、味精等一份);
放置(“已连接”);
关闭(袜子);
而(1),;
返回0;
}
服务器:

#include<stdio.h>
#include<string.h>    //strlen
#include<sys/socket.h>
#include<arpa/inet.h> //inet_addr
#include<unistd.h>    //write   
int main(int argc , char *argv[])
{   
    int socket_desc , client_sock , c , read_size;
    struct sockaddr_in server , client;
    char client_message[2000];

    //Create socket
    socket_desc = socket(AF_INET , SOCK_STREAM , 0);
    if (socket_desc == -1)
    {
        printf("Could not create socket");
    }
    puts("Socket created");

    //Prepare the sockaddr_in structure
    server.sin_family = AF_INET;
    server.sin_addr.s_addr = INADDR_ANY;
    server.sin_port = htons( 8888 );

    //Bind
    if( bind(socket_desc,(struct sockaddr *)&server , sizeof(server)) < 0)
    {
        //print the error message
        perror("bind failed. Error");
        return 1;
    }
    puts("bind done");

    //Listen
    listen(socket_desc , 3);

    //Accept and incoming connection
    puts("Waiting for incoming connections...");
    c = sizeof(struct sockaddr_in);

    //accept connection from an incoming client
    client_sock = accept(socket_desc, (struct sockaddr *)&client, (socklen_t*)&c);

    send(client_sock, "1", 1, 0);
    if (client_sock < 0)
    {
        perror("accept failed");
        return 1;
    }
    puts("Connection accepted");
    close(client_sock);
    puts("I am at While loop");
    while(1)
    {
    }
    return 0;
}
#包括
#包括//strlen
#包括
#包括//inet\u addr
#包括//写入
int main(int argc,char*argv[])
{   
int socket_desc,client_sock,c,read_size;
服务器、客户端中的结构sockaddr_;
char client_message[2000];
//创建套接字
socket\u desc=socket(AF\u INET,SOCK\u STREAM,0);
如果(套接字描述==-1)
{
printf(“无法创建套接字”);
}
放置(“已创建套接字”);
//在结构中准备sockaddr_
server.sinu family=AF\u INET;
server.sin\u addr.s\u addr=INADDR\u ANY;
server.sin_port=htons(8888);
//束缚
if(绑定(socket_desc,(struct sockaddr*)&server,sizeof(server))<0
{
//打印错误消息
perror(“绑定失败。错误”);
返回1;
}
看跌期权(“绑定完成”);
//听
听(插座描述,3);
//接受和传入连接
puts(“等待传入连接…”);
c=sizeof(结构sockaddr_in);
//接受来自传入客户端的连接
client\u sock=accept(socket\u desc,(struct sockaddr*)和client,(socklen\u t*)和c);
发送(客户端_sock,“1”,1,0);
如果(客户_sock<0)
{
perror(“接受失败”);
返回1;
}
看跌期权(“已接受连接”);
关闭(客户端_sock);
puts(“我在While循环”);
而(1)
{
}
返回0;
}
在客户端:
我在客户端添加了一个
recv
调用,该调用会一直阻塞,直到服务器实际发送某些内容为止

在服务器端:

我在accept呼叫之后添加了一个
send
呼叫。这确保只有已被接受的客户端才能继续其代码路径。

您的服务器接受第一个连接,然后无限循环一段时间(1)。你必须断开代码连接并进入循环。伙计们,运行他的代码。即使服务器在while循环中并且不接受任何东西,客户端代码中的connect部分也不会失败(我测试了它运行多个并行的客户端实例)。@alk您显然从未听说过listen backlog队列。@EJP:的确,我错过了队列中可能已完成的传入连接。如果您想等待,只需编写等待的代码。如果客户机需要知道服务器什么时候做了什么,那么服务器需要告诉客户机什么时候做了什么。我已经给出了backlog queue 100,但是结果是一样的。当然,结果是一样的,只是100个客户机可以做第二个客户机做的事情。我不明白你为什么认为它会改变。如果你想阻止它,你可以在调用connect之后在客户端调用recv,并在服务器端调用accept之后立即发送内容。recv调用将被阻止,因为没有数据到达该套接字,并且只有在服务器发送某个数据后才会释放(这发生在accept之后)。您能给出为什么客户端在未调用accept时接受与服务器的连接吗?@IshayPeled我运行这些代码不仅仅是为了开始使用套接字,我有一个完整的应用程序,其中我解决了这个问题为什么
MSG\u WAITFORONE
?有没有证据表明他想在事后进入非阻塞模式?@EJP你显然对这个问题非常了解,我在阅读你的答案和评论时学到了很多,请提供一个更好的答案,而不是抨击我的答案。用一种非被动的攻击性的方式来处理你的评论——这是我能想出的最快的例子,它实际上解决了他的问题,我不知道他的应用的全部范围,所以我不能确定
root@beaglebone:/home/Saad/test# ./client_test_1
Socket created
1Connected

Socket created
Connected
#include<stdio.h> //printf
#include<string.h>    //strlen
#include<sys/socket.h>    //socket
#include<arpa/inet.h> //inet_addr

int main(int argc , char *argv[])
{
    char buf[1];
    int sock;
    struct sockaddr_in server;
    char message[1000] , server_reply[2000];
    int ret;

    //Create socket
    sock = socket(AF_INET , SOCK_STREAM , 0);
    if (sock == -1)
    {
        printf("Could not create socket");
    }
    puts("Socket created");

    server.sin_addr.s_addr = inet_addr("127.0.0.1");
    server.sin_family = AF_INET;
    server.sin_port = htons( 8888 );

    //Connect to remote server
    ret = connect(sock , (struct sockaddr *)&server , sizeof(server));
    if (ret < 0)
    {
        perror("connect failed. Error");
        return 1;
    }
    recv(sock, buf, 1, MSG_WAITFORONE);

    puts("Connected\n");
    close(sock);
    while(1);
    return 0;
}
#include<stdio.h>
#include<string.h>    //strlen
#include<sys/socket.h>
#include<arpa/inet.h> //inet_addr
#include<unistd.h>    //write   
int main(int argc , char *argv[])
{   
    int socket_desc , client_sock , c , read_size;
    struct sockaddr_in server , client;
    char client_message[2000];

    //Create socket
    socket_desc = socket(AF_INET , SOCK_STREAM , 0);
    if (socket_desc == -1)
    {
        printf("Could not create socket");
    }
    puts("Socket created");

    //Prepare the sockaddr_in structure
    server.sin_family = AF_INET;
    server.sin_addr.s_addr = INADDR_ANY;
    server.sin_port = htons( 8888 );

    //Bind
    if( bind(socket_desc,(struct sockaddr *)&server , sizeof(server)) < 0)
    {
        //print the error message
        perror("bind failed. Error");
        return 1;
    }
    puts("bind done");

    //Listen
    listen(socket_desc , 3);

    //Accept and incoming connection
    puts("Waiting for incoming connections...");
    c = sizeof(struct sockaddr_in);

    //accept connection from an incoming client
    client_sock = accept(socket_desc, (struct sockaddr *)&client, (socklen_t*)&c);

    send(client_sock, "1", 1, 0);
    if (client_sock < 0)
    {
        perror("accept failed");
        return 1;
    }
    puts("Connection accepted");
    close(client_sock);
    puts("I am at While loop");
    while(1)
    {
    }
    return 0;
}