常用的几种网络协议HTTP/HTTPS、socket、TCP/UDP 、 及其c基础编程
HTTP/HTTPS处于应用层
socket处于会话层
TCP/UDP处于传输层
HTTPS是HTTP的加密版本应用了SSL。
socket简单来说式TCP/UDP的封装,是调用TCP/UDP的接口(API),套接字s_fd则是操作TCP/UDP的最小单位。
更加详细的内容可以到这篇博文中了解。最全的socket、tcp和http之间的区别和关系
HTTP/HTTPS编程
详细内容可以参考这篇博文,libcurl的http编程应用,这里只是做个简单的总结
get编程
struct curl_slist *headers = NULL;
headers = curl_slist_append(headers, "Accept: Agent-007");//创建一个张志参数的结构体headers(协议头)
curl_easy_init(); // 初始化
curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers);// 改协议头
curl_easy_setopt(curl, CURLOPT_URL,"http://www.baidu.com");
curl_easy_setopt(curl, CURLOPT_WRITEDATA, fp); //将返回的http头输出到fp指向的文件
curl_easy_setopt(curl, CURLOPT_HEADERDATA, fp); //将返回的html主体数据输出到fp指向的文件
curl_easy_perform(curl);//执行,上面的几步操作统称为设定参数,这一步才是真正执行的过程
curl_slist_free_all(headers);//清除和退出操作
curl_easy_cleanup(curl);
post编程
curl = curl_easy_init();//用于初始化,如果之前没有调用curl_globel_init()在这里则会自动调用
curl_easy_setopt(curl, CURLOPT_COOKIEFILE, "/tmp/cookie.txt"); // 指定cookie文件
curl_easy_setopt(curl, CURLOPT_POSTFIELDS, "&img1=%s&img2=%s&key=%s&secret=%s&typeId=%d&format=%s"); // 指定访问参数
curl_easy_setopt(curl, CURLOPT_URL, "https://netocr.com/api/faceliu.do"); // 指定url
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, readData);//这里的readData是回调函数的指针,回调函数需要一个特殊的格式
//size_t readData( void *ptr, size_t size, size_t nmemb, void *stream)
//ptr是获取的响应体的字符串指针,size和nmemb相乘就是整个的大小
curl_easy_cleanup(curl);//用于退出
socket编程
详细内容可以参考这篇博文,socket编程应用,这里只是将大概框架展示一下
服务器端(server端)
struct sockaddr_in s_addr;
struct sockaddr_in c_addr;
// int socket(int domain, int type, int protocol);
// 初始化获得socket套接字
s_fd = socket(AF_INET,SOCK_STREAM,0);
if(s_fd == -1){
perror("socket");
exit(-1);
}
// int bind(int sockfd, const struct sockaddr *addr,socklen_t addrlen);
// 绑定相应数据(端口,ip地址),都放在了结构体s_addr中
s_addr.sin_family = AF_INET;//TCP set
s_addr.sin_port = htons(atoi(argv[2]));//port set
inet_aton(argv[1],&s_addr.sin_addr) ;//ip address set
bind(s_fd,(struct sockaddr *)&s_addr,sizeof(struct sockaddr_in));
// int listen(int sockfd, int backlog)
// 设定accpet能够连接的客户端上限为10个
listen(s_fd,10);
// int accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen)
// 这里作为连接函数,一般放在循环里面,用fork或者pthread_create不断循环创建子进程或者线程
int c_addr_len = sizeof(struct sockaddr_in);
c_fd = accept(s_fd,(struct sockaddr *)&c_addr,&c_addr_len);
客户端编程(client端)
// inital
int c_fd;
char buf[128];
struct sockaddr_in c_addr;
memset(&c_addr,0,sizeof(struct sockaddr_in));
// int socket(int domain, int type, int protocol);
// 同样通过socket函数获取套接字
c_fd = socket(AF_INET,SOCK_STREAM,0);
if(c_fd == -1){
perror("socket");
exit(-1);
}
// int connect(int sockfd, const struct sockaddr *addr,socklen_t addrlen);
// 绑定相应的数据(端口,ip地址),在结构体c_addr中,然后通过connect函数触发server端的accpet函数
c_addr.sin_family = AF_INET;//TCP set
c_addr.sin_port = htons(atoi(argv[2]));//port set
inet_aton(argv[1],&c_addr.sin_addr) ;//ip address set
int cnt = connect(c_fd,(struct sockaddr *)&c_addr,sizeof(struct sockaddr_in));
if(cnt == -1){
perror("connect");
exit(-1);
}