Linux socket通讯编程

上一篇 / 下一篇  2013-05-13 13:36:01 / 个人分类:测试基础

    一个android的驱动层测试让我初步接触了下Linux socket通讯编程相关的基础知识。项目的client端软件与server端通过usb串口通信,项目需要修改为client与server端通过网口来通信。所以需要编写一个UDP通讯的client端去测试通讯是否正常以及server端相应数据是否正确。
    客户端通过socket通讯的大概流程是:建立socket、绑定bind、放送数据sendto、接收数据recvfrom、关闭通讯close。考虑到发送和接收如果有先后通讯顺序,会导致有数据延迟,或者容易buff满,所以发送和接收需要有两个独立的线程来处理。大致如下:


#include <sys/ioctl.h>
#include <net/if.h>
#include <netinet/in.h>
#include <arpa/inet.h>
 
#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
//#include <linux/in.h>
#include <string.h>
#include <termios.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <pthread.h>
 
#define PORT_SERV 8888
#define BUFF_LEN 256
 
unsigned char dectivate_buf[BUFF_LEN]=
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xEE,0x01,0x00};

unsigned char init_buf[BUFF_LEN]=
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xEE,0x01,0x01};

unsigned char set_resolution_buf[BUFF_LEN]=
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xEE,0x05,0x02,0x00,0x00,0x00,0x00};

unsigned char set_config_buf[BUFF_LEN]=
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xEE,0x05,0x03,0x00,0x00,0x00,0x00};

unsigned char start_scan_buf[BUFF_LEN]=
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xEE,0x01,0x04};

unsigned char set_freq_buf[BUFF_LEN]=
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xEE,0x07,0x08,0x00,0x00,0x00,0x00,0x00,0x00};

unsigned char set_touchsize_buf[BUFF_LEN]=
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xEE,0x05,0x09,0x00,0x00,0x00,0x00};
 
unsigned char set_activeled_buf[BUFF_LEN]=
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xEE,0x05,0x1D,0x00,0x00,0x00,0x00};

unsigned char single_scan_buf[BUFF_LEN]=
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xEE,0x03,0x0F,0x00,0x00};

unsigned char product_id_buf[BUFF_LEN]=
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xEE,0x01,0x29};

unsigned char status_buf[BUFF_LEN]=
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xEE,0x01,0x1E};

unsigned char suspend_buf[BUFF_LEN]=
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xEE,0x01,0x0A};

unsigned char resume_buf[BUFF_LEN]=
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xEE,0x01,0x06};

unsigned char validate_connect_buf[BUFF_LEN]=
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xEE,0x01,0xEF};

unsigned char invalid_notify__buf[BUFF_LEN]=
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xEE,0x02,0xFE,0x00};

int running = 1;

struct pthread_rec{
        int s;
        struct sockaddr_in *addr_serv;
        unsigned char read_buf[BUFF_LEN];
};


static int getch(void)
{
    struct termios oldt,newt;
    int ch;

    if (!isatty(STDIN_FILENO)) {
        fprintf(stderr, "this problem should be run at a terminal\n");
        exit(1);
    }
    // save terminal setting
    if(tcgetattr(STDIN_FILENO, &oldt) < 0) {
        perror("save the terminal setting");
        exit(1);
    }

    // set terminal as need
    newt = oldt;
    newt.c_lflag &= ~( ICANON | ECHO );
    if(tcsetattr(STDIN_FILENO,TCSANOW, &newt) < 0) {
        perror("set terminal");
        exit(1);
    }

    ch = getchar();

    // restore termial setting
    if(tcsetattr(STDIN_FILENO,TCSANOW,&oldt) < 0) {
        perror("restore the termial setting");
        exit(1);
    }
    return ch;
}

 static void udpclie_echo(int s, struct sockaddr *to, unsigned char *buff)
{   

    int n, i=0;
    unsigned char read_buff[BUFF_LEN];
    struct sockaddr_in from;
    int len = sizeof(*to);
    n = sendto(s, buff, BUFF_LEN, 0, to, len);
    if(n == -1)
    {
        printf("sendto error\n");
        return ;
    }

    printf("send successfully\n");
}

static void udpclie_rec(struct pthread_rec *t)
{
        int n,i=0;
        int len = sizeof(*(t->addr_serv));

        struct sockaddr_in from;
       
      // printf("s is %d",t->s);
       
        while(running)
    {
      // printf("running %d",running);   
        n = recvfrom(t->s, t->read_buf, BUFF_LEN, 0, (struct sockaddr *)&from, &len);
       // printf("n is %d", n);
        if(n == -1)
        {
                printf("recvfrom error\n");
                return ;
        }
        for(i=0; i<32;i++)
        {

                if(!(i%8))
                        printf("\n");
                printf("0x%x, ",t->read_buf[i]);
        }
            printf("\n");
        printf("continue to select num:\n");
    }
}


int main(int argc, char *argv[])
{
    int s;
    int key = 0;
    struct sockaddr_in addr_serv, addr_clie;   
//*******************************************************
    struct pthread_rec a;
        char str[16];
    int n;
        int ret_rec = -1;
        pthread_t pt_rec;
 
    printf("请输入服务器IP:\n");
    scanf("%s",str);
    printf("请输入服务器端口号(8888)\n");
    scanf("%d",&n);
   



//*************************************************
    s = socket(AF_INET, SOCK_DGRAM, 0);
      //  printf("s_send is %d",s);
    if(s < 0)
    {
        printf("socket err\n");
        return -1;
    }
//******************************************
    struct ifreq ifr;
    strcpy(ifr.ifr_name,"eth0");
    if(ioctl(s, SIOCGIFADDR, &ifr) < 0)
        perror("ioctl");
    printf("客户端IP:%s\n",inet_ntoa(((struct sockaddr_in *)&(ifr.ifr_addr))->sin_addr));


//*******************************************

    memset(&addr_serv, 0, sizeof(addr_serv));
    addr_serv.sin_family = AF_INET;
    addr_serv.sin_addr.s_addr = inet_addr(str);
    addr_serv.sin_port = htons(n);
        bind(s, (struct sockaddr*)&addr_serv, sizeof(addr_serv));

       a.s = s;
       a.addr_serv = &addr_serv;
   
       ret_rec=pthread_create(&pt_rec, NULL, (void*)udpclie_rec, &a);
       if(ret_rec != 0)
       {
                printf("can not creat thread for receiving data\n");
                return -1;
       }

    printf("select number:\n");
        while(1)
    {
        //set_buzzer_freq(freq);
        //printf( "\tFreq = %d\n", freq );
        //printf("select number:\n");
        key = getch();
        if(key != 10)
        {
            printf("you input is ");
            printf("%c\n",key);
        }

        switch(key) {
        case '0':
            udpclie_echo(s, (struct sockaddr *)&addr_serv, dectivate_buf);           
            break;
        case '1':
            udpclie_echo(s, (struct sockaddr *)&addr_serv, init_buf);       
            break;
        case '2':
            udpclie_echo(s, (struct sockaddr *)&addr_serv, set_resolution_buf);           
            break;
        case '3':
            udpclie_echo(s, (struct sockaddr *)&addr_serv, set_config_buf);           
            break;
        case '4': //single scanning
            udpclie_echo(s, (struct sockaddr *)&addr_serv, start_scan_buf);       
            break;
        case '5': //single scanning
            udpclie_echo(s, (struct sockaddr *)&addr_serv, set_freq_buf);           
            break;
        case '6': //single scanning
            udpclie_echo(s, (struct sockaddr *)&addr_serv, set_touchsize_buf);           
            break;
        case '7': //single scanning
            udpclie_echo(s, (struct sockaddr *)&addr_serv, set_activeled_buf);           
            break;
        case '8': //single scanning
            udpclie_echo(s, (struct sockaddr *)&addr_serv, single_scan_buf);       
            break;
        case '9': //single scanning
            udpclie_echo(s, (struct sockaddr *)&addr_serv, product_id_buf);   
            break;
        case 'a': //single scanning
            udpclie_echo(s, (struct sockaddr *)&addr_serv, status_buf);   
            break;

        case 'b':
            udpclie_echo(s, (struct sockaddr *)&addr_serv, suspend_buf);       
            break;
                case 'c':
                        udpclie_echo(s, (struct sockaddr *)&addr_serv, resume_buf);                   
                        break;
                case 'd':
                        udpclie_echo(s, (struct sockaddr *)&addr_serv, validate_connect_buf);                   
                        break;
                case 'e':
                        udpclie_echo(s, (struct sockaddr *)&addr_serv, invalid_notify__buf);                   
                        break;

        case 'z':
        case EOF:
            //stop_buzzer();
            exit(0);

        default:
            break;
        }
    }
    //udpclie_echo(s, (struct sockaddr *)&addr_serv);

    close(s);
    return 0;



}


TAG:

 

评分:0

我来说两句

Open Toolbar