C语言编写smtp用户代理之socket操作
来源:互联网 发布:文娱小说推荐知乎 编辑:程序博客网 时间:2024/06/05 16:45
一、函数的准备和功能介绍
首先是 renyj_sock.h文件
#ifndef RENYJ_SOCK_H#define RENYJ_SOCK_H #include<stdio.h>#include<string.h>#include<stdlib.h>#include<unistd.h>#include<sys/types.h>#include<sys/file.h>#include<sys/socket.h>#include<ctype.h>#include<netinet/in.h>#include<netdb.h>#include<sys/ioctl.h>#include<arpa/inet.h>#include<time.h>#include<signal.h>#include<errno.h>#include<sys/wait.h>#include<pwd.h>#include<grp.h>#include<fcntl.h>#include<limits.h>#ifdef HAS_SSL #include <openssl/ssl.h>#include <openssl/rand.h>#include <openssl/err.h>#endif/*宏定义用来打印调试信息*/#define debug(format,args...) do{fprintf(stderr,"Debug>>>%s->%s()->line.%d:"format"\n",__FILE__,__FUNCTION__,__LINE__,##args);}while(0);/*这个函数用来初始化socket并且返回一个可以使用的sokect描述符,第一个参数没有用,这里是为了扩展*/int myclient_sock(int protel,char *addr,int port,int timeout);/*这个函数用来从socket读取数据,供外界调用的接口函数*/int mysock_gets(char* str,int size,int timeout);/*这个函数用来从socket发送数据,提供给外界的接口函数*/int mysock_puts(char* str);/*从socket中读取数据,不提供给外界*/int mysock_read(int sock,char *str,int size,int timeout);/*向socket 发送数据,不提供给外界*/int mysock_write(int sock,char *str,int size);/*关闭socket*/int mysock_close();/*获取socket 描述符的值,提供给外界*/int get_socket();/*设置socket 描述符的值,提供给外界*/int set_socket(int socket);/*将IP或者域名的字符串转变成IP地址的函数,只支持IPv4*/struct in_addr *str_to_addr(char *addr);//由于使用qq邮箱需要加密传输,所以在这里需要开启ssl。#ifdef HAS_SSL//封装一个读取ssl加密后数据的函数 int mysock_read_ssl(SSL *ssl,char *str,int size,int timeout);//封装一个发送ssl数据的函数int mysock_write_ssl(SSL *ssl,char *str,int size); //获取SSL标志SSL* get_ssl();//设置ssl标志int set_ssl(SSL *ssl);//初始化 sslint openssl_init(char *cipher);//将某个socket描述符对应的socket传输的数据设置为ssl加密int turn_on_ssl(int fd);int turn_ssl_status_on();int turn_ssl_status_off();#endif#endif
二、函数的实现
renyj_sock.c文件
int renyj_fd;SSL *renyj_ssl;int renyj_ssl_status;/*初始化sokcet,准备连接*/int myclient_sock(int protel,char *seraddr,int port,int timeout){ struct sockaddr_in sa; struct in_addr* addr; int sock_fd; struct timeval tv; fd_set fdset; //获取IP地址 addr = str_to_addr(seraddr); if (NULL == addr) { debug("invalid domain"); return -1; } memset(&sa,0x00,sizeof(sa)); //准备通信地址 sa.sin_family = AF_INET; sa.sin_port = htons(port); sa.sin_addr.s_addr = addr->s_addr; //创建socket sock_fd = socket(AF_INET,SOCK_STREAM,PF_UNSPEC); if (-1 == sock_fd) { return -1; } //监控socket,如果连接超时,则退出。 int rc; rc = connect(sock_fd,(struct sockaddr*)(&sa),sizeof(sa)); if (-1 == rc) { debug("connect error"); return -1; } FD_ZERO(&fdset); FD_SET(sock_fd,&fdset); tv.tv_sec = timeout; tv.tv_usec = 0; rc = select(sock_fd+1,NULL,&fdset,NULL,&tv); if (-1 == rc) { debug("select error"); return -1; } if (0 == rc) { debug("connect to %s:%d timeout after %d seconds ", seraddr,port,timeout); return -1; } //返回一个socket描述符 return sock_fd;}
int mysock_gets(char *str, int size,int timeout){#ifdef HAS_SSL mysock_read_ssl(get_ssl(),str,size,timeout);#else mysock_read(get_socket(),str,size,timeout); #endif}
int mysock_puts(char *str){#ifdef HAS_SSL mysock_write_ssl(get_ssl(),str,strlen(str));#else mysock_write(get_socket(),str,strlen(str));#endif}
int mysock_read(int sock,char *str,int size,int timeout){ if (NULL == str) { return -1; } char *cur = str; char buff[1]; int count=0; char lastread = 0; int tmpcount = 0; while (10 != lastread) { tmpcount = recv(sock,buff,1,0); if (-1 == tmpcount) { debug("recv error"); return -1; } lastread = buff[0]; if ((count < size)&&(10 != lastread)&&(13!=lastread) ) { count++; *cur = lastread; cur++; } } if (count > 0) { *cur = 0; } return count;}
int mysock_write(int sock,char *str,int count){ int curcount = 0; int bytessent = 0; while (bytessent < count) { curcount = send(sock,str,count-bytessent,0); if (curcount < 0) { debug("send error"); return curcount; } bytessent = bytessent + curcount; str += curcount; } return count;}
int mysock_close(){ close(renyj_fd);}int get_socket(){ return renyj_fd;}int set_socket(int socket){ renyj_fd = socket;}
struct in_addr *str_to_addr(char *addr){ static struct in_addr myaddr; struct hostent *host; myaddr.s_addr=inet_addr(addr); if(-1!=myaddr.s_addr) { return (&myaddr); } host = gethostbyname(addr); if (NULL == host) { return NULL; } return (struct in_addr*)(*host->h_addr_list);}
#ifdef HAS_SSL SSL *get_ssl(){ return renyj_ssl;}int set_ssl(SSL *ssl){ renyj_ssl = ssl;}int openssl_init(char *cipher){ static const char rnd_seed[]="my huge entropy for rng.. blah"; SSL_CTX *ssl_ctx=(SSL_CTX *) NULL; SSL *ssl=NULL; SSL_library_init(); SSL_load_error_strings(); RAND_seed(rnd_seed,sizeof(rnd_seed)); OpenSSL_add_all_algorithms(); ssl_ctx=SSL_CTX_new(SSLv23_client_method()); if (ssl_ctx == NULL) { debug("Could not create SSL context\n"); return -1; } if (cipher) { if (!SSL_CTX_set_cipher_list(ssl_ctx,cipher)) { debug("Could not set cipher list %s\n",cipher); return -1; } } ssl=SSL_new(ssl_ctx); if (ssl == NULL) { debug("SSL_new() failed\n"); return -1; } /* set ssl to msock's static */ set_ssl(ssl);}int turn_on_ssl(int fd){ int rc=(-1); SSL *ssl; ssl = get_ssl(); if (ssl) { if (!SSL_set_fd(ssl,fd)) { debug("turn_on_raw_ssl: failed to set socket %d to SSL\n",fd); return(-1); } /* must set back to msock's static */ set_ssl(ssl); debug("connect ..."); rc=SSL_connect(ssl); if (rc < 1) { debug("turn_on_raw_ssl: SSL connection failed\n"); return(-1); } debug("connect end ") rc=0; return(0); } return(-1);}int turn_ssl_status_on(){ renyj_ssl_status = 1;}int turn_ssl_status_off(){ renyj_ssl_status = 0;}int mysock_write_ssl(SSL *ssl,char *str,int count){ int curcount = 0; int bytessent = 0; while (bytessent < count) { curcount = SSL_write(ssl,str,count-bytessent); if (curcount < 0) { debug("send error"); return curcount; } bytessent = bytessent + curcount; str += curcount; } return count;}int mysock_read_ssl(SSL *ssl,char *str,int size,int timeout){ if (NULL == str) { return -1; } char *cur = str; char buff[1]; int count=0; char lastread = 0; int tmpcount = 0; while (10 != lastread) { tmpcount = SSL_read(ssl,buff,1); if (-1 == tmpcount) { debug("recv error"); return -1; } lastread = buff[0]; if ((count < size)&&(10 != lastread)&&(13!=lastread) ) { count++; *cur = lastread; cur++; } } if (count > 0) { *cur = 0; } return count;}#endif
阅读全文
0 0
- C语言编写smtp用户代理之socket操作
- C语言编写smtp用户代理之协议操作
- 使用C语言编写一个smtp用户代理
- C语言编写smtp用户代理之代码综合和管理
- 【C++】【网络】利用Socket 编写SMTP 发送邮件程序
- linux socket tcp Server c语言编写
- C语言编写Socket程序---入门篇
- 用C语言编写Socket程序
- C语言编写windows用户账户管理
- 利用Socket 编写SMTP 发送邮件程序
- C语言之socket通信
- C语言文件操作函数的编写
- linux系列(一)C语言编写Socket程序
- 读《用C语言编写Socket程序》有感
- C语言编写Socket监听处理程序一例
- socket应用 用C语言编写发送邮件程序
- C语言练习之程序编写
- c语言练习之规范编写
- UVA-455Periodic Strings
- java语言特点
- nexus maven setting 和pom 文件配置
- Angular.js(四)
- Retrofit——API声明 2
- C语言编写smtp用户代理之socket操作
- ZOJ 2724 Windows Message Queue
- 缓存更新的套路
- oracle中的union和union all-yellowcong
- Hadoop+Zookeeper+HBase环境搭建
- js动态轮播图简便写法
- poj 3279
- 数据结构--------图
- UVA-70474Where is the Marble?