C套接字使用UDP阻塞write()调用,而在TCP中工作良好



我正在编写一个具有UDP和TCP的多服务服务器,我使用写入函数在服务器和客户端之间发送一个结构,如标题所述,在TCP客户端工作得很好,而它只是在执行这行后被困在写入函数

    printf ("while %lun",nleft);

代码如下:

服务器

#include <stdio.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <netinet/in.h>
#include <sys/types.h>
#include <netinet/tcp.h>
#include <errno.h>
#define MAXLINE 100

struct equation {
    float a;
    char c;
    float b;
};
struct result {
    long double res;
};
int MAX (int a,int b){
    if (a>b) return a;
    return b;
}

int readn(int fd, void *vptr, size_t n)
{
    size_t  nleft;
    ssize_t nread;
    char   *ptr;
    ptr = vptr;
    nleft = n;
    while (nleft > 0) {
        if ( (nread = read(fd, ptr, nleft)) < 0) {
            if (errno == EINTR)
                nread = 0;      /* and call read() again */
            else
                return (-1);
        } else if (nread == 0)
            break;              /* EOF */
        nleft -= nread;
        ptr += nread;
    }
    return (n - nleft);         /* return >= 0 */
}

int writen(int fd, const void *vptr, size_t n)
{
    size_t nleft;
    ssize_t nwritten;
    const char *ptr;
   // printf ("nI'm In %lun",n);
    ptr = vptr;
    nleft = n;
  //  printf ("%lu NNNNN  %lu SIZE %lu n",nleft,n,sizeof(*vptr));
    while (nleft > 0) {
        printf ("while %lun",nleft);
        fflush (stdout);
        if ( (nwritten = write(fd, ptr, nleft)) <= 0) {
            if (nwritten < 0 && errno == EINTR)
                nwritten = 0;   /* and call write() again */
            else
                return (-1);    /* error */
        }
        nleft -= nwritten;
        ptr += nwritten;
    }
    printf ("n 5alawees n");
// printf ("n%sn",vptr);
//    ffulsh (stdout);
    return (n);
}
void HandleClient(int comm_fd);
void Die (const char * msg)
{
    perror(msg);
    exit(1);
}
int passiveUDP (short port){
    struct sockaddr_in servaddr;
    int listen_fd;
    if ((listen_fd = socket(AF_INET, SOCK_DGRAM, 0)) < 0)
    {
        Die("Falied to create socket");
    };
    //printf ("%d" ,listen_fd);
    memset( &servaddr,0, sizeof(servaddr));
    servaddr.sin_family = AF_INET;
    servaddr.sin_addr.s_addr = htons(INADDR_ANY);
    servaddr.sin_port = htons(port);
    if (bind(listen_fd, (struct sockaddr *) &servaddr, sizeof(servaddr))<0)
    {
        Die("Failed to bind socket to address");
    }
    return listen_fd;
}
int passiveTCP (short port){
    struct sockaddr_in servaddr;
    int listen_fd;
    if ((listen_fd = socket(AF_INET, SOCK_STREAM, 0)) < 0)
    {
        Die("Falied to create socket");
    };
    memset( &servaddr,0, sizeof(servaddr));
    servaddr.sin_family = AF_INET;
    servaddr.sin_addr.s_addr = htons(INADDR_ANY);
    servaddr.sin_port = htons(port);
    if (bind(listen_fd, (struct sockaddr *) &servaddr, sizeof(servaddr))<0)
    {
        Die("Failed to bind socket to address");
    }
    if (listen(listen_fd, 10) < 0)
    {
        Die("Failed to listen on server socket");
    }
    return listen_fd;
}
int main(int argc, char * argv[])
{
    if (argc != 2) {
        fprintf(stderr, "USAGE: ./HelloITServer <port>n");
        exit(1);
    }
    char str[100];
    int listen_fd, comm_fd;
    int    usock = passiveUDP (atoi (argv[1]));               /* UDP socket  */
    int    tsock = passiveTCP (atoi (argv[1]));           /* TCP master socket  */
    int    nfds;
    fd_set rfds;                 /* readable file descriptors */
    struct sockaddr_in fsin;     /* the request from address */
    nfds = MAX(tsock, usock) + 1;
    FD_ZERO(&rfds);
    while (1) {
        FD_SET(tsock, &rfds);
        FD_SET(usock, &rfds);
        printf ("HELLO");
        if(select(nfds, &rfds, NULL, NULL, NULL) < 0){
            printf("select error: %d n",errno);
            exit (1);
        }
        if(FD_ISSET(tsock, &rfds))
        {
            /* TCP slave socket */
            //printf ("Hello TCP");
            int ssock;
            //int alen = sizeof(fsin);
            ssock = accept(tsock, (struct sockaddr *) NULL, NULL);
            if(ssock < 0)
                Die("accept failed: jkjkjkjkjkj n");
            HandleClient (ssock);
            close (ssock);
        }
        if(FD_ISSET(usock, &rfds))
        {
            printf ("Hello UDPn");
            HandleClient (usock);
        }
    }
}
void HandleClient(int comm_fd)
{
    struct equation eq;
    struct result rslt;
    bzero (&eq,sizeof (eq));
    bzero (&rslt, sizeof (rslt));
    if ((readn (comm_fd, &eq, sizeof(eq))) == 0){
        Die("Failed to receive from client");
    }
  //  printf ("n%lu  %lun",sizeof (struct result),sizeof (rslt));
    printf ("reciveed %f %c %fn",eq.a,eq.c,eq.b);
    switch (eq.c) {
        case '+':
            rslt.res = eq.a+eq.b;
            break;
        case '-':
            rslt.res = eq.a-eq.b;
            break;
        case '*':
            rslt.res = eq.a*eq.b;
            break;
        case '/':
            rslt.res = eq.a/eq.b;
            break;
        case '%':
            rslt.res = (int)eq.a% (int)eq.b;
            break;
        default:
            break;
    }
//    printf ("n%lun",sizeof(rslt));
//    printf ("n%lun",sizeof(rslt));
//    printf ("n%lun",sizeof(rslt));
    writen (comm_fd, &rslt, sizeof (rslt));
    //close (comm_fd);
}

客户端(以防你们需要)

#include <sys/types.h>
#include <sys/socket.h>
#include <netdb.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include<unistd.h>
#include <float.h>
#include <errno.h>
struct equation {
    float a;
    char c;
    float b;
};
struct result {
    long double res;
};
int readn(int fd, void *vptr, size_t n)
{
    size_t  nleft;
    ssize_t nread;
    char   *ptr;
    ptr = vptr;
    nleft = n;
    while (nleft > 0) {
        if ( (nread = read(fd, ptr, nleft)) < 0) {
            if (errno == EINTR)
                nread = 0;      /* and call read() again */
            else
                return (-1);
        } else if (nread == 0)
            break;              /* EOF */
        nleft -= nread;
        ptr += nread;
    }
    return (n - nleft);         /* return >= 0 */
}
int writen(int fd, const void *vptr, size_t n)
{
    size_t nleft;
    ssize_t nwritten;
    const char *ptr;
    ptr = vptr;
    nleft = n;
    while (nleft > 0) {
        if ( (nwritten = write(fd, ptr, nleft)) <= 0) {
            if (nwritten < 0 && errno == EINTR)
                nwritten = 0;   /* and call write() again */
            else
                return (-1);    /* error */
        }
        nleft -= nwritten;
        ptr += nwritten;
    }
    return (n);
}
int main(int argc,char *argv[])
{
    int sockfd,n;
    char sendline[100];
    char recvline[100];
    struct sockaddr_in servaddr;
    if (argc != 3) {
        fprintf(stderr, "USAGE: ./HelloClient <server_ip> <port>n");
        exit(1);
    }
    sockfd=socket(AF_INET,SOCK_DGRAM,0);
    bzero(&servaddr,sizeof servaddr);
    servaddr.sin_family=AF_INET;
    servaddr.sin_port= htons(atoi(argv[2]));
    inet_pton(AF_INET,argv[1],&(servaddr.sin_addr));
    connect(sockfd,(struct sockaddr *)&servaddr,sizeof(servaddr));
    struct result rslt;
    struct equation eq;
    //while(1)
    //{
    printf ("Accepted values by the program, from %f to %fn", FLT_MIN, FLT_MAX);
    printf ("n possible operations are addition, substraction, division, multiplication and modulo with operators : +,-,*,/,% respectivlyn");
    printf ("nPlease enter the equation in this form only : "5.0 + 2.0" with a single spacen");
    scanf ("%f %c %f", &eq.a,&eq.c,&eq.b);
    if (eq.c!='+' && eq.c!='-' && eq.c!='*' && eq.c!='/' && eq.c!='%'){
        printf ("n possible operations are addition, substraction, division, multiplication and modulo with operators : +,-,*,/,% respectivlyn");
        exit (1);
    }
    if (eq.c== '%'){
        if (!(eq.a == (float) ((int) eq.a) && eq.b == (float) ((int) eq.b))){
            printf ("Only integer values are accepted with the % operation, please rerun the programn");
            exit (1);
        }
    }
    //bzero( &eq, sizeof(eq));
    bzero( &rslt, sizeof(rslt) );
    //fgets(sendline,100,stdin); /*stdin = 0 , for standard input */
    writen (sockfd, &eq, sizeof(eq));
    readn (sockfd, &rslt, sizeof(rslt));
    printf("%Lfn thank you for using this marvelous calculator!n",rslt.res);
    bzero( &eq, sizeof(eq));
    exit (1);
    //}
}

我没有看到你在哪里添加IP地址。即使您只是想将环回地址用于测试目的,也需要执行更多的步骤。

查看Bind()部分,看看遗漏了什么。http://www.beej.us/guide/bgnet/output/html/multipage/bindman.html

相关内容

最新更新