예제 #1
0
void thread_error(int fd, const char *msg)
{
    printf("thread error: %s\n", msg);
    perror(msg);
    removeclient(fd);
    pthread_exit((void*)1);
}
예제 #2
0
파일: chatsvr.c 프로젝트: guptaak2/CSC209
/* select() said activity; check it out */
static void read_and_process(struct client *p)
{
    char msg[MAXHANDLE + 2 + MAXMESSAGE + 2 + 1];
    char *s = myreadline(p);
    if (!s)
	return;
    if (p->name[0]) {
	sprintf(msg, "%s: %s\r\n", p->name, s);
	broadcast(msg, strlen(msg));
    } else {
	strncpy(p->name, s, MAXHANDLE);
	p->name[MAXHANDLE] = '\0';
	cleanupstr(p->name);
	if (p->name[0]) {
	    printf("fd %d is using handle '%s'\n", p->fd, p->name);
	    sprintf(msg, "chatsvr: Welcome to our new participant, %s\r\n", p->name);
	    broadcast(msg, strlen(msg));
	} else {
	    static char botchmsg[] = "chatsvr: protocol botch\r\n";
	    write(p->fd, botchmsg, sizeof botchmsg - 1);
	    printf("Disconnecting fd %d because of protocol botch in handle registration\n", p->fd);
	    fflush(stdout);
	    close(p->fd);
	    removeclient(p);
	}
    }
}
예제 #3
0
파일: chatsvr.c 프로젝트: guptaak2/CSC209
static void broadcast(char *s, int size)
{
    struct client *p, *nextp;
    for (p = top; p; p = nextp) {
	nextp = p->next;  /* in case we remove this client because of error */
	if (p->name[0]) {
	    if (write(p->fd, s, size) != size) {
		perror("write()");
		removeclient(p);
	    }
	}
    }
}
예제 #4
0
int main(void)
{
    int h = 0;
	int f = 1;
    int clientfd, maxfd, nready, i, result;
    socklen_t len;
    struct sockaddr_in q;
    fd_set allset, rset;
	struct queue_list *clientlist = q_init(); //client fds
	struct queue_list *battlelist = q_init(); //battles
	struct queue_list *playerlist = q_init(); //players w/ stats, name etc.
	  
	int listenfd = bindandlisten();
    maxfd = listenfd;

    FD_ZERO(&allset);
    FD_SET(listenfd, &allset);
    

    while (1)
    {
        printf("server on %d iteration\n", h);
        h++;
        if (f == 1)
        {
            printf("server initialized! \n");
            f++;
        }
        rset = allset;
        		
		struct node *bb = battlelist->front;
        while (bb)
        {
			if (bb->content->status == 0)
			{
                 battle_end(bb->content, playerlist, 0);
			}
			bb = bb->next;
        }

        printf("attempting to create matches: ");
        if (matchmaking(playerlist, battlelist) == 1)//find match for two clients each iteration
        {
            printf("Battle created with pid %d !\n", bid);
			bid = bid + 1;
        }
        
        nready = select(maxfd + 1, &rset, NULL, NULL, NULL); //check if there is any client active


        if (nready == 0) // if no client is active
        {
            continue; //go back to the beginning.
        }

        else if (nready == -1) //error
        {
            perror("select");
            continue;
        }


        if (FD_ISSET(listenfd, &rset)) //check if listenfd active that connected by any client
        {
            printf("a new client is connecting\n");
            len = sizeof(q);
            
            if ((clientfd = accept(listenfd, (struct sockaddr *)&q, &len)) < 0)  //accept the client, *i think* it will reset listenfd to inactive
            {
                perror("accept");
                exit(1);
            }
            
            FD_SET(clientfd, &allset); //add the client fd in to the set of fd
   
            write(clientfd, "What is your name?\r\n", 20);

            if (clientfd > maxfd) 
            {
                maxfd = clientfd; //update max # of fd if needed
            }
            
            printf("connection from %s\n", inet_ntoa(q.sin_addr));
            addclient(clientfd, q.sin_addr, clientlist);

        }
        
        struct node *p; 
        for(i = 0; i <= maxfd; i++) //iterate through fd set and
        {
            if (FD_ISSET(i, &rset)) //check each connected client fd in the set of fd, if anyone becomes active.
            {
                for (p = clientlist->front; p != NULL; p = p->next)  //TODO: change this for new data structure
                {
                    if (p->content->fd == i)
                    {          
                        result = handle(clientlist, playerlist, p->content);
                        
                        if (result == -1 || result == 5) 
                        {
                            if (result == 5)
                            {
                                bid = battle_end(p->content->player, playerlist, 1);
                                printf("battle %d drops due to client disconnected\n", bid);
                            }
                            
							int tmp_fd = p->fd;
                            removeclient(p->content, clientlist);
                            FD_CLR(tmp_fd, &allset);
                            close(tmp_fd);
                        }
                        
                        break; 
                    }
                }
            }
        }
    }
    

}
예제 #5
0
int main (){
    int maxfd, listenfd, connfd, nread, i;
    char c = 'C';
    char temp;
    char *after;
    unsigned short block_crc;
    unsigned char char_block, crc_first, crc_second;
    char *dirname = "filestore";
    struct client *top = malloc(sizeof (struct client));
    top->fd = -1;
    top->next = NULL;
    struct client *p;
    fd_set allset;
    socklen_t clilen;
    struct sockaddr_in cliaddr, servaddr;
    listenfd = Socket(PF_INET, SOCK_STREAM, 0);
    memset(&servaddr, '\0', sizeof(servaddr));
    servaddr.sin_family = AF_INET;
    servaddr.sin_addr.s_addr = INADDR_ANY;
    servaddr.sin_port = htons(PORT);
    
    Bind (listenfd, (struct sockaddr *) &servaddr, sizeof (servaddr));
    Listen (listenfd, LISTENQ);
    while(1){
        fprintf(stderr, "Time to Select\n");
        maxfd = listenfd;
        FD_ZERO (&allset);
        FD_SET(listenfd, &allset);
        //loop through the linked list of clients to refresh the allset
        for (p = top; p->fd >=0; p = p->next){
            FD_SET (p->fd, &allset);
            if (p->fd > maxfd) maxfd = p->fd; //if the fd is larger than the maxfd, change maxfd.
        }
        Select(maxfd+1, &allset, NULL, NULL, NULL);
        //loop through the linked list until the fd corresponding to the client that is set is found
        for (p = top; p->fd >=0; p = p->next){
            if (FD_ISSET(p->fd, &allset)) break;
        }
        //if it is our listening socket then a new client has come
        if (FD_ISSET(listenfd, &allset)){ 
            newconnection(listenfd, &top);
        }
        // otherwise its one of our old clients
        else if(!p){ //if p is null, we have a problem
            fprintf(stderr,"uhoh\n");
            exit(1);
        }
        // if p exists, then we go through the states
        else {
            if(p){
                if (p->state == initial){
                    fprintf(stderr, "initial reading from client\n");
                    // read as many as you can up to 20 characters, leaving off where it last wrote
                    nread = read(p->fd, &(p->buf[p->inbuf]), sizeof(char)*(20 - p->inbuf));
                    if(nread<0){
                        perror("read");
                        removeclient(p->fd, &top);
                    }
                    //use inbuf as an index of where to write next, and how much more can be written
                    p->inbuf = p->inbuf + nread;
                    //transfer stuff in buf to filename until a network newline is reached
                    for (i = 0; i < 20; i++){
                        p->filename[i] = p->buf[i];
                        if (p->buf[i] == '\r'){ //once the network newline is found
                            p->filename[i] = '\0';//place a null character to end the string
                            p->state = pre_block; //change states
                            p->fp = open_file_in_dir(p->filename, dirname);  //open a file
                            p->inbuf = 0;// reset inbuf to be 0, going to write over buf from 0 index
                            if (write(p->fd, &c, 1)<0){ //send 'C' to client
                                perror("write");
                                removeclient(p->fd, &top);
                            }
                            break;
                        }
                    }
                    //if the network newline is not found in the 20 characters sent by client, error in filename, drop client
                    if (p->inbuf == 20){
                        fprintf(stderr, "filename was not found. filename must be less than 20 characters\n");
                        removeclient(p->fd, &top);
                    }
                }
                if (p->state == pre_block){
                    fprintf(stderr, "pre_block readering from client \n"); 
                    nread = read(p->fd, &temp, 1); //read a single character
                    if(nread<0){ //if there was a problem with nread then drop the client
                        perror("read");
                        removeclient(p->fd, &top);
                    }
                    if (temp== EOT){
                        temp = ACK;
                        if (write(p->fd, &temp, 1)<0){
                            perror("write");
                            removeclient(p->fd, &top);
                        }
                        fprintf(stderr, "finished\n");
                        removeclient(p->fd, &top);
                    }
                    if (temp == SOH){
                        p->blocksize = 132;
                        p->state = get_block;
                    }
                    if (temp == STX){
                        p->blocksize = 1028;
                        p->state = get_block;
                    }
                }
                if (p->state == get_block){
                    fprintf(stderr, "get_block readering from client \n"); 
                    /* reads into the buffer as much as it can upto the blocksize of the client
                     * and continues writing where it left off*/
                    nread = read(p->fd, &(p->buf[p->inbuf]), p->blocksize - p->inbuf);
                    if(nread < 0){
                        perror("read");
                        removeclient(p->fd, &top);
                    }
                    p->inbuf = p->inbuf + nread;
                    //once the entire block is received, go to the next state;
                    if (p->inbuf == p->blocksize) p->state = check_block;
                }
                if (p->state == check_block){
                    fprintf(stderr, "checking_block  client \n"); 
                    char_block = p->current_block;
                    /*removes client if block number and inverse don't match or block number is not
                     * what was expected. however if the blocknum is a previously received block num, send ack*/
                    if (255 - p->buf[0] !=  p->buf[1]){
                        fprintf(stderr, "block number and inverse do not match\n");
                        removeclient(p->fd, &top);
                    }
                    else if (char_block > p->buf[0]){
                        temp = ACK;
                        if(write(p->fd, &temp, 1)<0){
                            perror("write");
                            removeclient(p->fd, &top);
                        }
                    }
                    else if (char_block != p->buf[0]){
                        fprintf(stderr, "char_block is not correct\n");
                        removeclient(p->fd, &top);
                    }
                    //otherwise, need to check crc
                    else{
                        block_crc = crc_message (XMODEM_KEY, &(p->buf[2]), p->blocksize - 4);
                        crc_first = block_crc>>8;
                        crc_second = block_crc;
                        if ((crc_first != p->buf[p->blocksize -2]) || (crc_second != p->buf[p->blocksize -1])){
                            fprintf(stderr, "crc does not match \n");
                            temp = NAK;
                            if(write(p->fd, &temp, 1) < 0){
                                perror("write");
                                removeclient(p->fd, &top);
                            }
                        }
                        else{
                            temp = ACK;
                            fprintf(stderr, "writing to client ACK\n");
                            if (write (p->fd, &temp, 1)<0){
                                perror("write");
                                removeclient(p->fd, &top);
                            }
                           
                            if(fwrite(&(p->buf[2]), p->blocksize-4, 1, p->fp)<0){
                                perror("write");
                                exit(1);
                            }
                            p->state = pre_block;
                            p->current_block ++;
                            p->inbuf = 0;
                            if(p->current_block > 255) p->current_block = 1;
                        }
                    }
                }
            }
        }
    }
예제 #6
0
void* handle_client(void* fd)
{
    int n;
    int oldtype;
    int clientfd;
    int nickLen;
    char buffer[256];
    char *token;
    char usernick[256];
    clientfd = (*(int*)fd);     
    nickLen = 0;
    n = pthread_setcanceltype(PTHREAD_CANCEL_DEFERRED, &oldtype);
    if (n < 0)
        thread_error(clientfd, "ERROR in setcanceltype");

    addclientthread(clientfd, (pthread_t*)pthread_self());
    sendusercount(clientfd);
    
    while (1)
    {
        printf("handle client %d\n", clientfd);
        memset(buffer, 0, 256);
        n = read(clientfd, buffer, 255);
        if (n <= 0) 
        {
            thread_error(clientfd, "Client disconnected");
        }
        if (nickLen == 0)
        {
            token = strtok(buffer, " ");
            if (token == NULL)
                thread_error(clientfd, "ERROR client protocol");
            if (strcmp(token, USER) == 0)
            {
                token = strtok(NULL, " ");
                if (token == NULL)
                    thread_error(clientfd, "ERROR reading client message");
                
                nickLen = strlen(token);
                if (nickLen > 0 && nickLen <= 256)
                {
                    strcpy(usernick, (const char*)token);
                    addusernick(clientfd, (const char*)&usernick);
                }
                else 
                {
                    n = write(clientfd, ERROR, ERROR_LEN);
                }
                if (n < 0) 
                {
                    thread_error(clientfd, "ERROR writing to socket");
                }
            }
        }
        else
        {
            sendmessagefrom(clientfd, buffer);
        }
     }
     removeclient(clientfd);
     pthread_exit(NULL);
 }
예제 #7
0
파일: chatsvr.c 프로젝트: guptaak2/CSC209
char *myreadline(struct client *p)
{
    int nbytes;

    /* move the leftover data to the beginning of buf */
    if (p->bytes_in_buf && p->nextpos)
	memmove(p->buf, p->nextpos, p->bytes_in_buf);

    /* If we've already got another whole line, return it without a read() */
    if ((p->nextpos = extractline(p->buf, p->bytes_in_buf))) {
	p->bytes_in_buf -= (p->nextpos - p->buf);
	return(p->buf);
    }

    /*
     * Ok, try a read().  Note that we _never_ fill the buffer, so that there's
     * always room for a \0.
     */
    nbytes = read(p->fd, p->buf + p->bytes_in_buf, sizeof p->buf - p->bytes_in_buf - 1);
    if (nbytes <= 0) {
	if (nbytes < 0)
	    perror("read()");
	if (p->name[0]) {
	    char msg[MAXHANDLE + 40];
	    printf("Disconnecting fd %d, name %s\n", p->fd, p->name);
	    fflush(stdout);
	    sprintf(msg, "chatsvr: Goodbye, %s\r\n", p->name);
	    removeclient(p);
	    broadcast(msg, strlen(msg));
	} else {
	    printf("Disconnecting fd %d, no name\n", p->fd);
	    fflush(stdout);
	    removeclient(p);
	}
    } else {

	p->bytes_in_buf += nbytes;

	/* So, _now_ do we have a whole line? */
	if ((p->nextpos = extractline(p->buf, p->bytes_in_buf))) {
	    p->bytes_in_buf -= (p->nextpos - p->buf);
	    return(p->buf);
	}

	/*
	 * Don't do another read(), to avoid the possibility of blocking.
	 * However, if we've hit the maximum message size, we should call
	 * it all a line.
	 */
	if (p->bytes_in_buf >= MAXMESSAGE) {
	    p->buf[p->bytes_in_buf] = '\0';
	    p->bytes_in_buf = 0;
	    p->nextpos = NULL;
	    return(p->buf);
	}

    }

    /* If we get to here, we don't have a full input line yet. */
    return(NULL);
}
예제 #8
0
int main(void) {
    int clientfd, maxfd, nready;
    struct client *p;
    struct client *head = NULL;
    socklen_t len;
    struct sockaddr_in q;
    struct timeval tv;
    fd_set allset;
    fd_set rset;
    srand (time(NULL));

    int i;

    //Initialize a listening fd of the server.
    int listenfd = bindandlisten();

    // initialize allset and add listenfd to the
    // set of file descriptors passed into select
    FD_ZERO(&allset);
    FD_SET(listenfd, &allset);

    // maxfd identifies how far into the set to search
    maxfd = listenfd;

    while (1) {//keep running
        // make a copy of the set before we pass it into select
        rset = allset;
        /* timeout in seconds (You may not need to use a timeout for
        * your assignment)*/
        tv.tv_sec = 2; // change to 0 from 10
        tv.tv_usec = 0;  /* and microseconds */

        nready = select(maxfd + 1, &rset, NULL, NULL, &tv); //Select a ready fd descriptor(client) to read.
        if (nready == 0) {
            printf("No response from clients in %ld seconds\n", tv.tv_sec);
            continue;
        }

        if (nready == -1) {
            perror("select");
            continue;
        }

        if (FD_ISSET(listenfd, &rset)) {
            printf("a new client is connecting\n");
            len = sizeof(q);
            if ((clientfd = accept(listenfd, (struct sockaddr *)&q, &len)) < 0) {
                perror("accept");
                exit(1);
            }
            FD_SET(clientfd, &allset);
            if (clientfd > maxfd) {
                maxfd = clientfd;
            }
            printf("connection from %s\n", inet_ntoa(q.sin_addr));
            //sprintf("what is your name?");
            head = addclient(head, clientfd, q.sin_addr);
        }
        //Handle every client
        //printf("running\n");
        for(i = 0; i <= maxfd; i++) {
            if (FD_ISSET(i, &rset)) {
                for (p = head; p != NULL; p = p->next) {
                    if (p->fd == i) {//
                        int result = handleclient(p, head);
                        if (result == -1) {
                            int tmp_fd = p->fd;
                            head = removeclient(head, p->fd);
                            FD_CLR(tmp_fd, &allset);
                            close(tmp_fd);
                        }
                        break;
                    }
                }
            }
        }
    }
    return 0;
}