为什么在服务器端和客户端都调用recv并发送功能时使用客户端的文件描述符?

问题描述

Tcpserver

#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);
    }
}

TCPClient

#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,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,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,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,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程序中,recvsend是通过传递client_fd作为参数来调用的,而在Client程序中,recv和{{1通过传递send作为参数来调用}}。我想知道为什么在服务器端我们不像在客户端那样使用自己的套接文件描述符?

解决方法

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

客户端的fd描述符是一个connect()’ing套接字。接受连接后,它可以与服务器执行I / O。