现在的位置: 首页 > 自动控制 > 工业·编程 > 正文

C/C++网络编程总结

2019-07-01 06:28 工业·编程 ⁄ 共 5116字 ⁄ 字号 暂无评论

网络是用物理链路将各个孤立的工作站或主机相连在一起,组成数据链路,从而达到资源共享和通信的目的。

通信是人与人之间通过某种媒体进行的信息交流与传递。网络通信是通过网络将各个孤立的设备进行连接,通过信息交换实现人与人,人与计算机,计算机与计算机之间的通信。

网络通信中最重要的就是网络通信协议。当今网络协议有很多,局域网中最常用的有三个网络协议:MICROSOFT的NETBEUI、NOVELL的IPX/SPXTCP/IP协议。应根据需要来选择合适的网络协议。

网络协议就是网络之间沟通、交流的桥梁,只有相同网络协议的计算机才能进行信息的沟通与交流。这就好比人与人之间交流所使用的各种语言一样,只有使用相同语言才能正常、顺网络通信利地进行交流。从专业角度定义,网络协议是计算机在网络中实现通信时必须遵守的约定,也就是通信协议。主要是对信息传输的速率、传输代码、代码结构、传输控制步骤、出错控制等作出规定并制定出标准。

   C/C++的后台程序都需要进行网络通讯,其实现方法无非有两种:使用系统底层Socket或者使用已有的封装好的网络库(重量级的ACE,轻量级的有Libevent,Libev,libcurl,还有 Boost的ASIO)。

一. 系统底层的Socket编程

主要有以下6个步骤:

(1)socket()函数

(2)bind()函数

(3)listen()、connect()函数

(4)accept()函数

(5)read()、write()函数等

(6)close()函数

下面直接引用文章里的代码说明:

server端:

#include <stdio.h>

#include <stdlib.h>

#include <errno.h>

#include <string.h>

#include <sys/types.h>

#include <netinet/in.h>

#include <sys/socket.h>

#include <sys/wait.h>

#define MYPORT 3490 /*定义用户连接端口*/

#define BACKLOG 10 /*多少等待连接控制*/

main()

{

int sockfd, new_fd; /* listen on sock_fd, new connection on new_fd */

struct sockaddr_in my_addr; /* my address information */

struct sockaddr_in their_addr; /* connector's address information */

int sin_size;

if ((sockfd = socket(AF_INET, SOCK_STREAM, 0)) == -1) {

perror("socket");

exit(1);

}

my_addr.sin_family = AF_INET; /* host byte order */

my_addr.sin_port = htons(MYPORT); /* short, network byte order */

my_addr.sin_addr.s_addr = INADDR_ANY; /* auto-fill with my IP */

bzero(&(my_addr.sin_zero),; /* zero the rest of the struct */

if (bind(sockfd, (struct sockaddr *)&my_addr, sizeof(struct sockaddr))== -1)

{

perror("bind");

exit(1);

}

if (listen(sockfd, BACKLOG) == -1)

{

perror("listen");

exit(1);

}

while(1)

{ /* main accept() loop */

sin_size = sizeof(struct sockaddr_in);

if ((new_fd = accept(sockfd, (struct sockaddr *)&their_addr, &sin_size)) == -1) {

perror("accept");

continue;

}

printf("server: got connection from %s\n", \

inet_ntoa(their_addr.sin_addr));

if (!fork()) { /* this is the child process */

if (send(new_fd, "Hello, world!\n", 14, 0) == -1)

perror("send");

close(new_fd);

exit(0);

}

close(new_fd); /* parent doesn't need this */

while(waitpid(-1,NULL,WNOHANG) > 0); /* clean up child processes */

}

}

client端

#include <stdio.h>

#include <stdlib.h>

#include <errno.h>

#include <string.h>

#include <sys/types.h>

#include <netinet/in.h>

#include <sys/socket.h>

#include <sys/wait.h>

#define PORT 3490 /* 客户机连接远程主机的端口 */

#define MAXDATASIZE 100 /* 每次可以接收的最大字节 */

int main(int argc, char *argv[])

{

int sockfd, numbytes;

char buf[MAXDATASIZE];

struct hostent *he;

struct sockaddr_in their_addr; /* connector's address information */

if (argc != 2) {

fprintf(stderr,"usage: client hostname\n");

exit(1);

}

if ((he=gethostbyname(argv[1])) == NULL) { /* get the host info */

herror("gethostbyname");

exit(1);

}

if ((sockfd = socket(AF_INET, SOCK_STREAM, 0)) == -1) {

perror("socket");

exit(1);

}

their_addr.sin_family = AF_INET; /* host byte order */

their_addr.sin_port = htons(PORT); /* short, network byte order */

their_addr.sin_addr = *((struct in_addr *)he->h_addr);

bzero(&(their_addr.sin_zero),; /* zero the rest of the struct */

if(connect(sockfd,(struct sockaddr *)&their_addr,sizeof(struct sockaddr)) == -1) {

perror("connect");

exit(1);

}

if ((numbytes=recv(sockfd, buf, MAXDATASIZE, 0)) == -1) {

perror("recv");

exit(1);

}

buf[numbytes] = '\0';

printf("Received: %s",buf);

close(sockfd);

return 0;

}

二.  常用开源socket库

1. ACE

     ACE是一个大型的中间件产品,代码20万行左右,过于宏大,一堆的设计模式,架构了一层又一层,使用的时候,要根据情况,看你从那一层来进行使用。支持跨平台。(详细资料可查看: http://www.cs.wustl.edu/~schmidt/ACE.html)

2. Boost的ASIO

         Boost的ASIO是一个异步IO库,封装了对Socket的常用操作,简化了基于Socket程序的开发。它开源、免费、支持跨平台。(详细资料可查看:http://think-async.com/)

3. libevent

          libevent是一个C语言写的网络库, 官方主要支持的是类linux操作系统, 最新的版本添加了对windows的IOCP的支持。由于IOCP是异步IO,与linux下的POLL模型,EPOLL模型,还有freebsd的KQUEUE等这些同步模型在用法上完全不一致,所以使用方法也不一样,就好比ACE中的Reactor和Proactor模式一样,使用起来需要转变思路。如果对性能没有特别的要求,那么使用libevent中的select模型来实现跨平台的操作, select模型可以横跨windows, linux, unix,solaris等系统。(详细资料可查看: http://libevent.org/)

4.  libev

         libev是一个C语言写的,它是一个C语言写的,只支持Linux系统的库,以前的时候只封装了EPOLL模型.使用方法类似libevent,但是非常简洁,代码量是最少的一个库,也就几千行代码。显然这样的代码跨平台肯定是无法支持的了,如果你只需要在Linux下面运行,那用这个库也是可以的。(详细资料可查看:http://software.schmorp.de/pkg/libev.html)

5.  Linux Socket Programming In C++

详细资料可查看:http://tldp.org/LDP/LG/issue74/tougher.html)

6.  C++ Sockets Library

它是一个跨平台的Sockets库,实现包括TCP、UDP、ICMP、SCTP协议。已实现的应用协议包括有SMTP、HTTP(S)、Ajp。具有SOCKS客户端实现以及匿名DNS,支持HTTP的GET/POST/PUT以及WebServer的框架。(详细参考资料可查看: http://www.alhem.net/Sockets/index.html)

7. Simple Socket

这个类库让编写基于Socket的客户/服务器程序更加容易。(详细资料可查看:http://home.kpn.nl/lcbokkers/simsock.htm)

8.  POCO

          POCO C++ Libraries提供一套C++的类库用以开发基于网络的可移植的应用程序,功能涉及线程、线程同步、文件系统访问、流操作、共享库和类加载、套接字以及网络协议包括:HTTP、FTP、SMTP等;其本身还包含一个HTTP服务器,提供XML的解析和SQL数据库的访问接口。POCO库的模块化、高效的设计及实现使得POCO特别适合嵌入式开发。在嵌入式开发领域,由于C++既适合底层(设备I/O、中断处理等)和高层面向对象开发,越来越流行。(详细资料可查看:http://pocoproject.org/)

9.   Libcurl

免费的轻量级的客户端网络库,支持DICT, FILE, FTP, FTPS, Gopher, HTTP, HTTPS, IMAP, IMAPS,LDAP, LDAPS,POP3, POP3S, RTMP, RTSP, SCP, SFTP, SMTP, SMTPS, Telnet, TFTP.支持SSL, HTTPPOST,HTTPPUT, FTP上传, HTTP form上传,代理,cookies,用户名与密码认证。(详细资料可查看:http://curl.haxx.se/libcurl/)

10.  libiop

一个c语言开发的跨平台网络IO库。功能特性:c/c++api,底层支持epoll,select,poll等io模型;异步事件模型;任务池模型,跨平台线程接口;跨平台(Linux/windows);日志服务;稳定,支持7*24小时无间断运行,自动处理异常状态;高并发与快速响应;API简洁,学习成本低。(详细资料可查看: http://sourceforge.net/projects/libiop/)

11.Muduo

muduo 是一个基于 Reactor 模式的现代 C++ 网络库,它采用非阻塞 IO 模型,基于事件驱动和回调,原生支持多核多线程,适合编写 Linux 服务端多线程网络应用程序。视频连接:http://v.youku.com/v_show/id_XNDIyNDc5MDMy.html,性能对比:http://www.oschina.net/p/muduo

使用 C++11 以及 Makefile 进行构建,详情请看https://github.com/AlexStocks/muduo

给我留言

留言无头像?