为什么我的C程序在写入时随机失败?

时间:2015-11-08 00:21:51

标签: c multithreading sockets

我编写了一个代理,它接受来自host1的连接,并将连接转发给server2。

我接受一个连接然后我启动两个线程来处理连接...一个线程从主机1接收并发送到server2,另一个线程接收表单server2并发送到host1。

我的程序编译时没有错误,当我运行它并连接主机1时,我的程序在短时间后在函数WRITE失败,没有错误。

连接正常,在写入之前,它在短时间内失败。

您也可以找到我正在使用的书面功能。 当控制器写入套接字时,代码在CONTROLLER线程失败。

为什么程序失败而根本没有错误消息?

/*
 *     File Server0.c
 *    ECHO TCP SERVER with the following features:
 *      - Gets port from keyboard
 *      - SEQUENTIAL: serves one client at a time
 */
#define _POSIX_SOURCE
#include    <stdio.h>
#include    <stdlib.h>
#include    <string.h>
#include    <inttypes.h>
#include    "mysocket.h"
#include <arpa/inet.h>
#include <fcntl.h> // for open
#include <unistd.h> // for close
#include <sys/types.h>
#include <signal.h>
#include <sys/wait.h>
#include <pthread.h> /* POSIX threads */

#define RBUFLEN        16384

/* FUNCTION PROTOTYPES */
int mygetline(char * line, size_t maxline, char *prompt);
int writen(SOCKET, char *, size_t);
void *mininet(void *);
void *controller(void *);

SOCKET             s,s1[100],d[100];
int y=0,z=0;

int main()
{
    uint16_t         lport_n, lport_h;
    int             result;
    socklen_t addrlen;
    struct sockaddr_in     saddr, caddr;
    //fd_set readfds;
    SOCKET             conn_request_skt;
    int             bklog = 2,t=0;
    pthread_t tid1[100];
    pthread_t tid[100];

    /* Initialize socket API if needed */
    SockStartup();

    /* input server port number */
    lport_h=8888;
    lport_n = htons(lport_h);

    /* create the MININET socket */
    printf("Creating first socketn");
    s = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);

    if (s == INVALID_SOCKET)
        err_fatal("socket() failed");

    printf("done, socket number %un",s);

    /* bind the MININET socket to any local IP address */
    saddr.sin_family      = AF_INET;
    saddr.sin_port        = lport_n;
    saddr.sin_addr.s_addr = INADDR_ANY;
    showAddr("Binding to address first socket", &saddr);
    result = bind(s, (struct sockaddr *) &saddr, sizeof(saddr));

    if (result == -1)
        err_fatal("bind() failed");

    printf("done.n");

    /* listen on MININET socket */
    printf ("Listening at socket %d with backlog = %d n",s,bklog);
    result = listen(s, bklog);

    if (result == -1)
        err_fatal("listen() failed");

    printf("done.n");
    conn_request_skt=s;

    /* accept next connection from mininet */
    for(;;)
    {
        addrlen = sizeof(struct sockaddr_in);
        z++;
        y++;
        t++;
        d[t] = accept(conn_request_skt, (struct sockaddr *) &caddr, &addrlen);

        if (d[t] == INVALID_SOCKET)
            err_fatal("accept() failed");

        showAddr("Accepted connection from", &caddr);
        printf("new accepted connection socket: %un",d[t]);

        /* serve the client on socket s */
        pthread_create(&tid[t], NULL, mininet, &t);
        pthread_create(&tid1[t], NULL, controller, &t);
        sleep(1);
    }
    exit(0);
}

void *mininet (void *arg)
{
    char            buf[RBUFLEN];        /* reception buffer */
    int             n,t,k;
    t=y;
    k=z;

    printf("MININET: m is: %d, c is: %d n ", t,k);

    /* main server loop */
    for (;;)
    {
        printf("MININET receiving on socket: %un",d[t]);
        n=recv(d[t], buf, RBUFLEN-1, 0);
        if (n < 0)
        {
            printf("MININET Read errorn");
            closesocket(d[t]);
            printf("MININET Socket %d closedn", d[t]);
            return NULL;
        }
        else if (n==0)
        {
            printf("Connection closed by MININET on socket %dn",d[t]);
            closesocket(d[t]);
            break;
        }
        else
        {
            printf("Received line from MININET socket %03d :n", d[t]);
            buf[n]=0;
            printf("[%s]n",buf);
            printf("MINET WRITING TO: %un",s1[k]);
            if(writen(s1[k], buf, n) != n)
            printf("Write error while replying TO CONTROLERn");
            else
            printf("Reply sent towards CONTROLERn");
        }
    }
    return NULL;
}

void *controller (void *arg)
{
    char             buf[RBUFLEN];        /* reception buffer */
    uint16_t         lport_n1, lport_h1;    /* port where the server listens (net/host byte ord resp.) */
    int             result, n,t,k;
    struct sockaddr_in saddr1;        /* server and client address structures */
    t=y;
    k=z;

    printf("CONTROLLER: m is: %d, c is: %d n ", t,k);

    /* Initialize socket API if needed */
    SockStartup();
    lport_h1=6633;
    lport_n1 = htons(lport_h1);
    printf("Creating CONTROLLER socketn");
    s1[k] = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);

    if (s1[k] == INVALID_SOCKET)
        err_fatal("socket() failed");

    printf("done, socket number %un",s1[k]);

    /* bind the socket to any local IP address */
    saddr1.sin_family      = AF_INET;
    saddr1.sin_port        = lport_n1;
    saddr1.sin_addr.s_addr = INADDR_ANY;

    /* connect */
    showAddr("Connecting to target CONTROLER address", &saddr1);
    result = connect(s1[k], (struct sockaddr *) &saddr1, sizeof(saddr1));

    if (result == -1)
        err_fatal("connect() failed");

    printf("done.n");

    /* main server loop */
    for (;;)
    {
        printf("CONTROLER receiving on socket: %un",s1[k]);
        n=recv(s1[k], buf, RBUFLEN-1, 0);
        if (n < 0)
        {
            printf("CONTROLER Read errorn");
            closesocket(s1[k]);
            printf("Socket %d closedn", s1[k]);
            return NULL;
        }
        else if (n==0)
        {
            printf("Connection closed by CONTROLER on socket %dn",s1[k]);
            closesocket(s1[k]);
            return NULL;
        }
        else
        {
            printf("Received line from CONTROLER socket %03d :n", s1[k]);
            buf[n]=0;
            printf("[%s]n",buf);
            printf("CONTROLER writing on socket: %un",d[t]);
            if(writen(d[t], buf, n) != n)
                printf("Write error while replying TO MININETn");
            else
                printf("Reply sent towards MININETn");
        }
    }
    return NULL;
}

/* Gets a line of text from standard input after having printed a prompt string Substitutes end of line with ''
   Empties standard input buffer but stores at most maxline-1 characters in the passed buffer
*/
int mygetline(char *line, size_t maxline, char *prompt)
{
    char    ch;
    size_t  i;
    printf("%s", prompt);
    for (i=0; i< maxline-1 && (ch = getchar()) != 'n' && ch != EOF; i++)
    *line++ = ch;
    *line = '';
    while (ch != 'n' && ch != EOF)
    ch = getchar();
    if (ch == EOF)
        return(EOF);
    else
        return(1);
}

/* Writes nbytes from buffer ptr to stream socket s */
int writen(SOCKET s, char *ptr, size_t nbytes)
{
    size_t nleft;
    ssize_t nwritten;
    for (nleft=nbytes; nleft > 0; )
    {
        nwritten = send(s, ptr, nleft, 0);
        if (nwritten <=0)
            return (nwritten);
        else
        {
            nleft -= nwritten;
            ptr += nwritten;
        }
    }
    return (nbytes - nleft);
}

0 个答案:

没有答案