您的位置:首页 > 理论基础 > 计算机网络

如果使用socket发送http请求(并且编译成可以被lr调用的压力测试脚本)

2015-04-17 12:04 609 查看
#include <unistd.h>

#include <sys/types.h> /* basic system data types */

#include <sys/socket.h> /* basic socket definitions */

#include <netinet/in.h> /* sockaddr_in{} and other Internet defns */

#include <arpa/inet.h> /* inet(3) functions */

#include <netdb.h> /*gethostbyname function */

#include <sys/time.h>

#include <time.h>

#include <stdlib.h>

#include <errno.h>

#include <stdio.h>

#include <string.h>

#include<openssl/rsa.h>

#include<openssl/pem.h>

#include<openssl/err.h>

#define OPENSSLKEY "/test.key"

#define PUBLICKEY "/test_pub.key"

#define BUFFSIZE 1024

#define MAXLINE 10240

char *my_encrypt(char *str,char *path_key){

char *p_en;

RSA *p_rsa;

FILE *file;

int flen,rsa_len;

if((file=fopen(path_key,"r"))==NULL){

perror("open key file error");

return NULL;

}

if((p_rsa=PEM_read_RSA_PUBKEY(file,NULL,NULL,NULL))==NULL){

//if((p_rsa=PEM_read_RSAPublicKey(file,NULL,NULL,NULL))==NULL){ 换成这句死活通不过,无论是否将公钥分离源文件

ERR_print_errors_fp(stdout);

return NULL;

}

flen=strlen(str);

rsa_len=RSA_size(p_rsa);

p_en=(unsigned char *)malloc(rsa_len+1);

memset(p_en,0,rsa_len+1);

if(RSA_public_encrypt(rsa_len,(unsigned char *)str,(unsigned char*)p_en,p_rsa,RSA_NO_PADDING)<0){

return NULL;

}

RSA_free(p_rsa);

fclose(file);

return p_en;

}

char *my_decrypt(char *str,char *path_key){

char *p_de;

RSA *p_rsa;

FILE *file;

int rsa_len;

if((file=fopen(path_key,"r"))==NULL){

perror("open key file error");

return NULL;

}

if((p_rsa=PEM_read_RSAPrivateKey(file,NULL,NULL,NULL))==NULL){

ERR_print_errors_fp(stdout);

return NULL;

}

rsa_len=RSA_size(p_rsa);

p_de=(unsigned char *)malloc(rsa_len+1);

memset(p_de,0,rsa_len+1);

if(RSA_private_decrypt(rsa_len,(unsigned char *)str,(unsigned char*)p_de,p_rsa,RSA_NO_PADDING)<0){

return NULL;

}

RSA_free(p_rsa);

fclose(file);

return p_de;

}

EVP_PKEY * getKey(char * key_path) {

X509 *cert = NULL;

BIO *in = NULL;

EVP_PKEY *key;

in = BIO_new_file(key_path, "r");

cert = PEM_read_bio_X509(in, NULL, NULL, NULL);

if (cert != NULL) {

key = (EVP_PKEY *) X509_get_pubkey(cert);

} else {

in = BIO_new_file(key_path, "r");

key = PEM_read_bio_PUBKEY(in, NULL,NULL, NULL);

}

BIO_free(in);

if (cert) {

X509_free(cert);

}

return key;

}

char *my_encrypt2(unsigned char *str,int * plen){

int cryptedlen;

unsigned char *cryptedbuf;

int i=0;

EVP_PKEY *key;

key = getKey(PUBLICKEY);

*plen = EVP_PKEY_size(key);

cryptedbuf = malloc((*plen) + 1);

memset(cryptedbuf,0,(*plen)+ 1);

if(RSA_public_encrypt(strlen(str),(unsigned char *)str,cryptedbuf,key->pkey.rsa,RSA_PKCS1_PADDING)<0){

return NULL;

}

EVP_PKEY_free(key);

for(i=0;i<128;i++) {

printf(" %d ", (unsigned char)cryptedbuf[i]);

}

printf("\n");

return cryptedbuf;

}



int opensocket(char *ip,int port)

{

int connfd;

char * servInetAddr = ip;

int servPort = port;

char dataBuffer[MAXLINE];

struct sockaddr_in servaddr;

//设置超时时间

struct timeval timeout={30,0};//3s

//connfd = socket(AF_INET, SOCK_STREAM, 0);

if ((connfd=socket(AF_INET,SOCK_STREAM,0))== -1)

{

perror("socket");

return 0;

}

if (setsockopt(connfd,SOL_SOCKET,SO_SNDTIMEO,(const char*)&timeout,sizeof(timeout)) == -1)

{

perror("setsockopt");

return 0;

}

bzero(&servaddr, sizeof(servaddr));

servaddr.sin_family = AF_INET;

servaddr.sin_port = htons(servPort);

inet_pton(AF_INET, servInetAddr, &servaddr.sin_addr);



if (connect(connfd, (struct sockaddr *) &servaddr, sizeof(servaddr)) < 0) {

perror("connect error");

return -1;

}

else{

//return 1;

return connfd;

}

}

void closesocket(int connfd){

close(connfd);

}

int msgsend(int connfd,char *msg, int len){

char dataBuffer[MAXLINE];

bzero(dataBuffer,MAXLINE+1);

strncpy(dataBuffer,msg,strlen(msg));

int errSend = send(connfd,dataBuffer,len,0);

if(-1 == errSend)

{

return -1;

}else{

return 1;

}

}

//对rsa加密后的数据进行发送

int rsa_msgsend(int connfd,char * source)

{

char *ptr_en,*ptr_de;

char send_msg[1024];

int plen=0;

ptr_en=my_encrypt2(source,&plen);

char head[150];

sprintf(head, "POST /auth HTTP/1.1\r\nHost: bjcm01.portal.freemse.360.cn\r\nAccept-Version: 1\r\nAppId:1\r\nUser-Agent:MSE 8.0.0;Android 5.0\r\nContent-Length: %d\r\n\r\n", plen);

printf("plen :%d \n",plen);

// printf("source is :%s\n",start);

//ptr_de=my_decrypt(ptr_en,OPENSSLKEY);

//printf("jiemi data %s\n",ptr_de);

//sprintf(send_msg,"%s%s",start,ptr_en);

//printf("send_msg %s\n",start);

int h_send_result = msgsend(connfd,head, strlen(head));

printf("head: %s\n",head);

int b_send_result = msgsend(connfd,ptr_en, plen);

printf("ptr_en: %s\n",ptr_en);

if( h_send_result == -1 || b_send_result == -1){

return -1;

}

else{

return 1;

}

}

//对比返回的结果

int cmprecvmsg(int connfd,char *msg,int len){

char dataBuffer[MAXLINE];

bzero(dataBuffer,MAXLINE+1);

int recv_bytes = recv(connfd,dataBuffer,MAXLINE,0);

//return dataBuffer;

if(recv_bytes < 0)

{

return -2;

}

if(memcmp(dataBuffer,msg,len)==0){

return 1;

}else{

return -1;

}

}

int gettimeofday(struct timeval *tv, struct timezone *tz);

int httpSendAndRcv(int sockfd,char *realhost){

struct timeval t_start,t_end;

long cost_time = 0;

#define BUFSIZE 1024

int ret, i,j, h;

struct sockaddr_in servaddr;

char str1[4096], str2[4096], buf[BUFSIZE];

socklen_t len;

fd_set t_set1;

struct timeval timeout={5,0}; //select等待5秒,5秒轮询,要非阻塞就置0

//发送数据

memset(str1, 0, 4096);//一定要初始化一下该内存,因为在测试时发现发送的字符串有一些脏数据

strcat(str1, "GET / HTTP/1.1\n");

strcat(str1, "Host: test.com\r\n");

strcat(str1, "RealHost:");

strcat(str1, realhost);

strcat(str1, "\r\n");

strcat(str1, "Content-Type: application/x-www-form-urlencoded");

strcat(str1, "\r\n\r\n");

printf("%s\n",str1);



gettimeofday(&t_start, NULL);



long start = ((long)t_start.tv_sec)*1000+(long)t_start.tv_usec/1000;//为了获取毫秒的时间,只有将秒和微妙都转成毫秒来计算了

printf("Start time: %ld ms\n", start);

ret = write(sockfd,str1,strlen(str1));

if (ret < 0) {

printf("发送失败!错误代码是%d,错误信息是'%s'\n",errno, strerror(errno));

exit(0);

}else{

printf("消息发送成功,共发送了%d个字节!\n\n", ret);

}

while(1){

//sleep(1);

FD_ZERO(&t_set1);

FD_SET(sockfd, &t_set1);

h= 0;

// printf("--------------->1");

h= select(sockfd +1, &t_set1, NULL, NULL, &timeout);

//printf("--------------->2");

if (h == 0) break; //如果在超时时间内没有数据返回认为http的response接受完毕,可以进行下一轮请求

if (h < 0) {

close(sockfd);

printf("在读取数据报文时SELECT检测到异常,该异常导致线程终止!\n");

return -1;

};

if (h > 0){

memset(buf, 0, 4096);

i= read(sockfd, buf, 4095);

if (i==0){

close(sockfd);

printf("读取数据报文时发现远端关闭,该线程终止!\n");

return -1;

}

// printf("recive");

printf("%s\n", buf);

}

}



//获取结束时间

gettimeofday(&t_end, NULL);

long end = ((long)t_end.tv_sec)*1000+(long)t_end.tv_usec/1000;

printf("End time: %ld ms\n", end);

//统计网页响应的时间差(当然包括了一次超时时间)

cost_time = end - start;

printf("Cost time: %ld ms\n", cost_time);



return 0;

}

//测试用

int main()

{

//unsigned char *source="{\"phone\":\"10002415407\", \"token\":\"47\", \"wid\":\"1\"}";

char *source="{\"phone\":\"1212121212\", \"token\":\"121212121\", \"wid\":\"wid\"}";

//char *ptr_en,*ptr_de;

char *ip="127.0.0.1";

int port=80

int connfd;

char buf[20];

char buf1[5];

char * realhost="m.so.com";

// char send_msg[1024];

char dataBuffer[21700];

int j;

//int plen=0;

//ptr_en=my_encrypt2(source,&plen);

//char start[150];

//sprintf(start, "POST /auth HTTP/1.1\r\nHost: bjcm01.portal.freemse.360.cn\r\nAccept-Version: 1\r\nUser-Agent:MSE 8.0.0;Android 5.0\r\nContent-Length: %d\r\n\r\n", plen);

//printf("plen :%d \n",plen);

// printf("source is :%s\n",start);

//ptr_de=my_decrypt(ptr_en,OPENSSLKEY);

//printf("jiemi data %s\n",ptr_de);

connfd=opensocket(ip,port);

//sprintf(send_msg,"%s%s",start,ptr_en);

//printf("send_msg %s\n",start);

// msgsend(connfd,start, strlen(start));

//msgsend(connfd,ptr_en, plen);

rsa_msgsend(connfd,source);

recv(connfd,dataBuffer,21700,0);

sscanf(dataBuffer, "%*[^\"]%[^m]", buf);

sscanf(buf, "%*[^:]:%[^,]", buf1);

printf("recv %s\n",dataBuffer);

printf("%s\n",buf1);

for (j=0;j<3;j++) msgrecv(connfd,realhost);

closesocket(connfd);

return 0;

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐