Chinaunix首页 | 论坛 | 博客
  • 博客访问: 9292
  • 博文数量: 13
  • 博客积分: 590
  • 博客等级: 中士
  • 技术积分: 140
  • 用 户 组: 普通用户
  • 注册时间: 2010-11-10 09:41
文章分类
文章存档

2010年(13)

我的朋友
最近访客

分类:

2010-11-28 16:09:31

用struct 和 函数指针可以方便的实现OO,包括继承,不过构造函数不能作为struct下的一个op, 而应该单独拿出来作为一个init函数。 在建立struct以后进行调用。

声明


#ifndef __mysock__
#define __mysock__

#include<unistd.h>
#include<errno.h>
#include<sys/types.h>
#include<sys/wait.h>
#include<sys/socket.h>
#include<netinet/in.h>
#include<arpa/inet.h>
#include<netdb.h>
#include<netinet/in.h>
#include<stdio.h>
#include<string.h>


#define true 1
#define false 0

typedef int bool;

typedef struct Mysock{
    int err;
    char errstr[128];
    int sockfd;

    struct sockaddr_in host;
    void (*init_mysock)(struct Mysock *ms);
    bool (*connected)(struct Mysock *ms);
    int (*my_sendmsg)(struct Mysock *ms, char * buf, int len);
    int (*my_recvmsg)(struct Mysock *ms, char * buf, int len);
    int (*sendline)(struct Mysock *ms, char *buf);
    int (*recvline)(struct Mysock *ms, char *buf);
    void (*my_quit)(struct Mysock *ms);
    void (*dealerr)(struct Mysock *ms);
}mysock;


typedef struct Mysock_client{    
    mysock cli_sock;
    int (*conn)(struct Mysock_client *msc, char *server_str, char *port_str);
} mysock_client;

typedef struct Mysock_server{
    mysock serv_sock;
    bool (*conn)(struct Mysock_server *mms, char *port_str);
} mysock_server;

void init_mysock_server(mysock_server *mss);

void init_mysock_client(mysock_client *msc);

#endif


实现:


#include "mysock.h"
#include<string.h>


/* -------- class mysock -------- */


bool connected(mysock *ms){
    return (ms->sockfd != -1);
}

int my_sendmsg(mysock *ms, char * buf, int len){
    if(!ms->connected(ms)){
        ms->err = 1;
        strcpy(ms->errstr, "Not connected.");
        return -1;
    }
    if (send(ms->sockfd, buf, len, 0) < len){
        ms->err = 1;
        strcpy(ms->errstr, "Data Not Send.");
        return -1;
    }
    ms->err = 0;
    return len;
}

int my_recvmsg(mysock *ms, char * buf, int len){
    int recv_len = -1;
    if(!ms->connected(ms)){
        ms->err = errno;
        strcpy(ms->errstr, "Not connected.");
        return -1;
    }
    recv_len = recv(ms->sockfd, buf, len, 0);
    if(recv_len == -1){
        ms->err = errno;
        strcpy(ms->errstr, "Data Not Received");
        return -1;
    }
    ms->err = 0;
    return recv_len;
}

int sendline(mysock *ms, char * buf){
    int i= 0;
    for (; buf[i] != '\r' && buf[i] != '\n' && buf[i] != '\0'; ++i){
        ms->my_sendmsg(ms, buf+i, 1);
        if(ms->err)
            return -1;
    }
    i += ms->my_sendmsg(ms, (char *)"\r\n", 2);
#if DEBUG == 1
    printf("--> %s", buf);
#endif
    return i;
}

int recvline(mysock *ms, char * buf){
    int i = 0, recv_len = 0;
    do{
        recv_len = ms->my_recvmsg(ms, buf+i, 1);
        if(ms->err) return -1;
        if(i >= 1023) break;
    }while(recv_len == 1 && buf[i++] != '\n');
    buf[i] = 0;
    printf("<-- %s", buf);
    return i;
}

void my_quit(mysock *ms){
    close(ms->sockfd);
}

void dealerr(mysock *ms){
    if (ms->err){
        perror(ms->errstr);
        close(ms->sockfd);
        return(errno);
    }
}

void init_mysock(mysock *ms){
    ms->sockfd = -1;
    ms->err = 0;
    ms->connected = connected;
    ms->my_sendmsg = my_sendmsg;
    ms->my_recvmsg = my_recvmsg;
    ms->sendline = sendline;
    ms->recvline = recvline;
    ms->my_quit = my_quit;
    ms->dealerr = dealerr;
    
}

/* -------- class mysock_client -------- */

int cli_conn(mysock_client *msc, char *server_str, char *port_str){
    struct hostent *he;
    int port;
    printf("in cli_coonn\n");
    msc->cli_sock.sockfd = socket(PF_INET, SOCK_STREAM, 0);
    
    if (msc->cli_sock.sockfd == -1){
        msc->cli_sock.err = errno;
        strcpy(msc->cli_sock.errstr, "socket");
        return false;
    }
    printf("socket create success\n");
    msc->cli_sock.host.sin_family = AF_INET;

    if(sscanf(server_str, "%*d.%*d.%*d.%*d") == 4){ //IP

        he = gethostbyaddr(server_str, 4, AF_INET);
    }else{ //Domain Name

        he = gethostbyname(server_str);
    }
    if (he == NULL) {
        msc->cli_sock.err = 1;
        strcpy(msc->cli_sock.errstr, "gethostbyaddr");
        return false;
    }
    msc->cli_sock.host.sin_addr = *((struct in_addr*)he->h_addr);

    sscanf(port_str, "%d", &port);
    printf("Port:\t%d\n", port);
    msc->cli_sock.host.sin_port = htons(port);

    //bzero(&host.sin_zero, 8);

    memset(&msc->cli_sock.host.sin_zero, 0, 8);

    if (connect(msc->cli_sock.sockfd, (struct sockaddr*)&(msc->cli_sock.host), sizeof(msc->cli_sock.host)) == -1){
        msc->cli_sock.err = 1;
        strcpy(msc->cli_sock.errstr, "connect");
        return false;
    }

    msc->cli_sock.err = 0;
    return true;
}

void mysock_client_con(mysock_client *msc, char *server_str, char *port_str){
    (*msc->conn)(msc, server_str, port_str);
}

void init_mysock_client(mysock_client *msc){
    init_mysock(&msc->cli_sock);
    msc->conn = cli_conn;
}
/* -------- class mysock_server -------- */


bool serv_conn(mysock_server *mss, char *port_str){
    int port;
    struct sockaddr_in hostaddr;
    int new_fd;
    struct sockaddr_in clientaddr;
    
    socklen_t sin_size = sizeof(struct sockaddr_in);
    sscanf(port_str, "%d", &port);

    if ((mss->serv_sock.sockfd = socket(AF_INET, SOCK_STREAM, 0)) == -1){
        perror("socket");
        return false;
    }

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

    memset(&hostaddr.sin_zero, 0, 8);

    if(bind(mss->serv_sock.sockfd, (struct sockaddr *) &hostaddr, sizeof(struct sockaddr)) == -1){
        perror("bind");
        return false;
    }

    if (listen(mss->serv_sock.sockfd, 1) == -1){
        perror("listen");
        return false;
    }

    if((new_fd = accept(mss->serv_sock.sockfd , (struct sockaddr *)&clientaddr, &sin_size)) == -1){
        perror("accept");
        return false;
    }

    printf("(t=%u)Server: accepted from %s\n",
            (unsigned int)time(NULL), inet_ntoa(clientaddr.sin_addr));
    while(true){
        ;
    }
    close(new_fd);
}


void mysock_server_con(mysock_server *mss, char *port_str){
    (*mss->conn)(mss,port_str);
}

void init_mysock_server(mysock_server *mss){
    init_mysock(&mss->serv_sock);
    mss->conn = serv_conn;
}


使用:



#include"mysock.h"

#include<string.h>

#define DBG(a) printf("%s = %d\n", #a, a)
#define NOOP ((char*)"NOOP\r\n")

struct Mysock_client client;
struct Mysock_server server;

char * host = NULL;
char port[6]= "21";
char username[1024];
char password[1024];
char buf[1024];
char buf1[1024];
bool pasv = true;
char pasv_port[20];
bool set_pasv();
void dologin();
void shell();
void lcd();
void pwd();
void cd();
void get();
void put();
void del();
void dir();
void my_quit();

int main(int argc, char * argv[]){
    
    /*    init    */
    int len, status;
    int i;
    char cmd[30];
        
    init_mysock_client(&client);
    init_mysock_server(&server);

    if(argc < 2){
        printf("Usage: %s \n", argv[0]);
        exit(1);
    }
    host = argv[1];
    if(argc > 2)
        strcpy(port, argv[2]);

    printf("host : %s port %s\n", argv[1], port);
    
    mysock_client_con(&client, host, port);
    printf("connect success\n");
    
    if( (*client.cli_sock.connected)(&(client.cli_sock)) == false) {
        printf("Can't connect to server (%s:%p)\n", host, port);
        return 1;
    }
    (*client.cli_sock.sendline)(&(client.cli_sock),NOOP);

    while (len = (*client.cli_sock.recvline)(&client.cli_sock, buf), len > 0){
        buf[len] = 0;
        sscanf(buf, "%d", &status);
        if(status != 220) break;
    }
    dologin();

    while (true){
        printf("ftp> ");
        if(gets(buf) == NULL) my_quit();
        sscanf(buf, "%10s", cmd);
        for(i = 0; cmd[i]; ++i){
            if(cmd[i] <= 'z' && cmd[i] >= 'a')
                cmd[i] -= 32;
        }
        if(cmd[0] == '!'){
            shell();
        }else if(strcmp(cmd, "LCD") == 0){
            lcd();
        }else if(strcmp(cmd, "PWD") == 0){
            pwd();
        }else if(strcmp(cmd, "CD") == 0){
            cd();
        }else if(strcmp(cmd, "GET") == 0){
            get();
        }else if(strcmp(cmd, "PUT") == 0){
            put();
        }else if(strcmp(cmd, "DEL") == 0){
            del();
        }else if(strcmp(cmd, "DIR") == 0){
            dir();
        }else if(strcmp(cmd, "my_quit") == 0){
            quit();
        }else{
            printf("Illegal Command. Supported commands are: \n");
            printf("lcd, pwd, cd, put, get, del, dir, my_quit.\n");
            printf("Command with a prefix \"!\" will run in the shell.\n");
        }
    }
    return 0;
}

void dologin(){
    int len;
    int status;
    while(true){
        
        printf("Username: ");
        scanf("%s", username);
        getchar();
        sprintf(buf, "USER %s\r\n", username);
        (*client.cli_sock.sendline)(&client.cli_sock, buf);
        (*client.cli_sock.recvline)(&client.cli_sock, buf);
        sscanf(buf, "%d", &status);
        if(status != 331) continue;

        printf("Password: ");
        scanf("%s", password);
        getchar();
        sprintf(buf, "PASS %s\r\n", password);
        (*client.cli_sock.sendline)(&client.cli_sock, buf);
        (*client.cli_sock.recvline)(&client.cli_sock, buf);
        sscanf(buf, "%d", &status);
        if(status == 230)break;
    }
}

void put(){
    char file[1024], *p;
    int len;
    FILE* fp;
    mysock_client sender;
    init_mysock_client(&sender);
    
    for (p = buf; *p; p++){
        if(*p == ' ') {
            p++;
            break;
        }
    }
    strcpy(file, p);
    fp = fopen(file, "r");
    if (fp == NULL){
        printf("Can't open file\n");
        return;
    }
    set_pasv();
    sprintf(buf1, "STOR %s\r\n", file);
    printf("%s", buf1);
    (*client.cli_sock.sendline)(&client.cli_sock, buf1);
    if(pasv){
        (*sender.conn)(&sender, host, pasv_port);
        if((*sender.cli_sock.connected)(&sender.cli_sock) == false){
            printf("Unable to connect to server (%s:%s)\n", host, pasv_port);
        }
        (*client.cli_sock.recvline)(&client.cli_sock, buf);
        while(len = fread(buf, 1, 1000, fp), len > 0){
            (*sender.cli_sock.my_sendmsg)(&sender.cli_sock, buf, len);
            if(len < 1000)
                break;
        }
        (*sender.cli_sock.my_quit)(&sender.cli_sock);
        (*client.cli_sock.recvline)(&client.cli_sock, buf);
        printf("Data transferred.\n");
    }else{
        printf("Not pasv. Not Completed.\n");
    }
    fclose(fp);
}

void pwd(){
    int i;
    (*client.cli_sock.sendline)(&client.cli_sock, (char *)"PWD\r\n");
    (*client.cli_sock.recvline)(&client.cli_sock, buf);
}

void cd(){
    int len = strlen(buf);
     char *p;
    if(len == 2) {
        pwd();
        return;
    }
    buf[len+1] = 0;

    for (p = buf; *p; p++){
        if(*p == ' ') break;
    }
    sprintf(buf1, "CWD%s\r\n", p);
    (*client.cli_sock.sendline)(&client.cli_sock, buf1);
    (*client.cli_sock.recvline)(&client.cli_sock, buf);
}

void get(){
    char *p, file[1024];
    int len;    
    int status;
    int datalen;
        char f_buf[64];
         FILE *fp ;
         mysock_client recver;
    p = NULL;

    init_mysock_client(&recver);

    for (p = buf; *p; p++){
        if(*p == ' ') {
            p++;
            strcpy(file, p);
            printf("FILE: %s~\n", file);
            break;
        }
    }
    set_pasv();
    (*client.cli_sock.sendline)(&client.cli_sock, (char*)"TYPE I\r\n");
    (*client.cli_sock.recvline)(&client.cli_sock, buf1);
    sprintf(buf1, "RETR %s\r\n", file);
    (*client.cli_sock.sendline)(&client.cli_sock, buf1);
    if(pasv){
        (*recver.conn)(&recver, host, pasv_port);
        if((*recver.cli_sock.connected)(&recver.cli_sock) == false){
            printf("Unable to connect to server (%s:%s)\n", host, pasv_port);
        }
        (*client.cli_sock.recvline)(&client.cli_sock, buf);

        sscanf(buf, "%d", &status);
        if(status == 550){
            (*recver.cli_sock.my_quit)(&recver.cli_sock);
            return;
        }

        for(p = buf;*p != '('; p++);
        sscanf(p, "(%d", &datalen);
        printf("Data length: %d\n", datalen);
        (*client.cli_sock.recvline)(&client.cli_sock, buf);
        
       fp = fopen(file, "w");
        if (fp == NULL){
            printf("Can't open file for write\n");
            return;
        }
        while(datalen > 0){
            if (datalen >= 64){
                len = (*recver.cli_sock.my_recvmsg)(&recver.cli_sock, f_buf, 64);
                fwrite(f_buf, 1, 64, fp);
            }else{
                len = (*recver.cli_sock.my_recvmsg)(&recver.cli_sock, f_buf, datalen);
                fwrite(f_buf, 1, datalen, fp);
                break;
            }
            datalen -= 64;
        }
        fclose(fp);
        (*recver.cli_sock.my_quit)(&recver.cli_sock);
        printf("Data transferred.\n");
    }else{
        printf("Not pasv. Not Completed.\n");
    }
}

void dir(){
    int i;
    mysock_client recver;
    init_mysock_client(&recver);
    
    set_pasv();
    (*client.cli_sock.sendline)(&client.cli_sock, (char*)"LIST\r\n");
    if(pasv){
        (*recver.conn)(&recver, host, pasv_port);
        if((*recver.cli_sock.connected)(&recver.cli_sock) == false){
            printf("Unable to connect to server (%s:%s)\n", host, pasv_port);
        }
        (*client.cli_sock.recvline)(&client.cli_sock, buf);
        while(true){
            i = (*recver.cli_sock.my_recvmsg)(&recver.cli_sock,buf, 64);
            buf[i] = 0;
            printf("%s", buf);
            if(i < 64) break;
        }
        (*recver.cli_sock.my_quit)(&recver.cli_sock);
        (*client.cli_sock.recvline)(&client.cli_sock, buf);
        //printf("Data transferred.\n");

    }else{
        printf("Not pasv. Not Completed.\n");
    }
}

void quit(){
    (*client.cli_sock.sendline)(&client.cli_sock, (char*)"my_quit\r\n");
    (*client.cli_sock.recvline)(&client.cli_sock, buf);
    (*client.cli_sock.my_quit)(&client.cli_sock);

}

bool set_pasv(){
    int status;
    int i;
    (*client.cli_sock.sendline)(&client.cli_sock, (char*)"PASV\r\n");
    (*client.cli_sock.recvline)(&client.cli_sock, buf);
    sscanf(buf, "%d", &status);
    if(status == 227){
        pasv = 1;
        for(i = 0; buf[i]; ++i){
            if(buf[i] == '('){
                int a, b;
                sscanf(buf+i, "(%*d,%*d,%*d,%*d,%d,%d)", &a, &b);
                sprintf(pasv_port, "%d", a * 256 + b);
                printf("PASV PORT: %s\n", pasv_port);
                break;
            }
        }
        return true;
    }else{
        pasv = 0;
        return false;
    }
}

void shell(){
    if(buf[1] == 0) return;
    system(buf+1);
}

void lcd(){
    char *p;
    for (p = buf; *p; p++){
        if(*p == ' ') break;
    }
    if(*p == 0) {
        system("pwd");
        return;
    }
   
    p++;
    if(chdir(p) == 0){
        printf("Changed to %s\n", p);
    }else{
        printf("Failed to change to %s\n", p);
    }
}

void del(){
    char buf1[1024];
    char *p;
    int len = strlen(buf);
    if(len == 3) return;
  
    for (p = buf; *p; p++){
        if(*p == ' ') break;
    }
    sprintf(buf1, "DELE%s\r\n", p);
    (*client.cli_sock.sendline)(&client.cli_sock, buf1);
    (*client.cli_sock.recvline)(&client.cli_sock, buf);
}


阅读(387) | 评论(0) | 转发(0) |
0

上一篇:dd 用法

下一篇:pthread three base Definitions

给主人留下些什么吧!~~