【问题标题】:Why is the client's file descriptor used while calling the recv and send funtions on both server and client sides?为什么在服务器端和客户端调用 recv 和 send 函数时都使用客户端的文件描述符?
【发布时间】:2021-01-30 18:25:06
【问题描述】:

TCP服务器

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

int main()
{
    int fd = socket(AF_INET, SOCK_STREAM, 0);
    if(fd == -1)
    {
        printf("socket failed!\n");
        exit(0);
    }
    printf("Enter port: ");
    int port;
    scanf("%d",&port);
    struct sockaddr_in server;
    server.sin_family = AF_INET;
    server.sin_port = htons(port);
    server.sin_addr.s_addr = INADDR_ANY;

    int bind_ret = bind(fd, (struct sockaddr*)(&server), sizeof(server));
    if(bind_ret == -1)
    {
       printf("bind failed!\n");
       exit(0);
    }

    int listen_ret = listen(fd, 10);
    if(listen_ret == -1)
    {
           printf("listen failed!\n");
           exit(0);
    }

    struct sockaddr_in client;
    int l = sizeof(client);
    int client_fd = accept(fd, (struct sockaddr*)(&client), &l);
    if(client_fd == -1)
    {
        printf("accept failed!\n");
        exit(0);
    }

    while(1)
    {
        char msg_recv[50];
        int recv_ret = recv(client_fd, msg_recv, sizeof(msg_recv),0);
        if(recv_ret == -1)
        {
            printf("recv failed!\n");
            exit(0);
        }
    
        msg_recv[recv_ret]='\0';
        if(strcmp("bye",msg_recv)==0)
        {
            exit(0);
        }
    
        printf("Message recieved: %s\n",msg_recv);
    
        char msg_send[50];
        printf("Enter message: ");
        scanf(" %s",msg_send);
        int send_ret = send(client_fd, msg_send, strlen(msg_send),0);
        if(send_ret == 0)
        {
            printf("send failed!\n");
        }
    
        if(strcmp("bye",msg_send) == 0)
         exit(0);
    }
}

TCP客户端

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

int main()
{ int fd = socket(AF_INET, SOCK_STREAM, 0);
  if(fd == -1)
  { 
    printf("socket failed!\n");
    exit(0);
  }

  int port;
  printf("Enter port number: ");
  scanf("%d",&port);

  struct sockaddr_in client;

  client.sin_family = AF_INET;
  client.sin_port = htons(port);
  client.sin_addr.s_addr = INADDR_ANY;

  int connect_ret = connect(fd, (struct sockaddr*)(&client), sizeof(client));
  if(connect_ret == -1)
  {
    printf("connect failed!\n");
    exit(0);
  }

  while(1)
  {
    printf("Enter message: ");
    char msg_send[50];
    scanf("%s",msg_send);

    int send_ret = send(fd, msg_send, strlen(msg_send), 0);
    if(send_ret == -1)
    {
        printf("send failed!\n");
        exit(0);
    } 

    if(strcmp("bye", msg_send)==0)
    {
        exit(0);
    }

    char msg_recv[50];
    int recv_ret = recv(fd, msg_recv, sizeof(msg_recv), 0);
    if(recv_ret == -1)
    {
        printf("recv failed!\n");
        exit(0);
    }
    msg_recv[recv_ret]= '\0';
    if(strcmp("bye", msg_recv) == 0)
     exit(0);
 
    printf("Message recieved: %s \n",msg_recv);
  }
 }

在上面的Server程序中,recv和send是通过传递client_fd作为参数调用的,而在Client的程序中,recv和send是通过传递fd作为参数调用的论点。我想知道为什么在服务器端我们没有像在客户端那样使用它自己的套接字文件描述符?

【问题讨论】:

  • 答案很简单:尝试将第二个客户端连接到您的服务器!

标签: sockets tcpclient send recv tcpserver


【解决方案1】:

服务器的fd 描述符是一个listen()'ing 套接字。它不能执行任何 I/O,只能接收传入的客户端连接。 accept() 从 fd 的队列中拉出一个挂起的客户端连接,并返回一个可以与该客户端执行 I/O 的新套接字描述符。

客户端的fd描述符是一个connect()'ing socket。一旦连接被接受,它就可以与服务器执行 I/O。

【讨论】:

    猜你喜欢
    • 2021-05-24
    • 2013-03-29
    • 1970-01-01
    • 2018-01-20
    • 1970-01-01
    • 2011-08-20
    • 1970-01-01
    • 1970-01-01
    • 2017-06-27
    相关资源
    最近更新 更多