一起talk C栗子吧(第一百五十八回:C语言实例--基于AF_INET域的流套接字通信)
2016-05-29 19:41
309 查看
各位看官们,大家好,上一回中咱们说的是基于AF_UNIX域的数据报套接字通信的例子,这一回咱们说的例子是:基于AF_INET域的流套接字通信 。闲话休提,言归正转。让我们一起talk C栗子吧!
看官们,我们在上一回中一起制作了我们的第二道佳肴是:基于AF_UNIX域的数据报套接字通信。今天,我将和大家一起制作第三道佳肴:基于AF_INET域的流套接字通信。
制作第三道佳肴的菜谱:流套接字过程。
制作第三道佳肴的食材:流套接字的接口,套接字属性,套接字地址信息。
看官们,以上的内容,我们在前面章回中都详细介绍过,如果大家忘记的话,可以参考前面的内容,重点是第一百四十七回的内容,因为这是我们的菜谱。在食材中最麻烦是套接字地址信息,大家可以参考一百五十五回中的例子。多说无益,我们通过具体的代码来演示。
看官们,以上是核心代码,完整的代码放到了我的资源中,大家可以点击这里下载使用。
关于上面的代码,我做一些补充说明:
我们首先获取套接字地址的信息,然后才创建套接字,虽然与菜谱中的顺序不一致,但是这种做法是合理 的,因为我们以前创建套接字的时候,都是直接在函数中写入套接字的属性。在这里,我们使用了getaddrinfo函数的结果,这种方法可以提高代码的移植性。这种方法,也使用在了bind函数中。
我们在通信中使用了localhost主机,并且给它指定了端口号:1080。在指定端口号时,它的数值需要大于1024。因为Linux系统给小于1024的端口绑定了专门的服务。
在释放套接字的同时,我们与要释放存放套接字地址信息的链表。
与使用Unix域套接字通信的例子相比, 主要是设置套接字属性和地址的方式不同,通信过程中读取和接收数据的方式是相同的。
我们需要把服务器端的代码和客户端的代码分别进行编译,并且编译成不同的可以执行文件:
看官们,美味佳肴做好了,我们一起来品尝下,品尝方法就是运行程序,下面是程序的运行结果,请大家参考:
看官们,从上面的运行结果中可以看到,客户端通过套接字发送数据给服务器,而服务器通过套接字接收客户端发来的数据,这样客户端和服务器端可以通过套接字进行通信。另外,我们进行了两次通信,通信的次数可以自己控制,甚至写成无限次也是可以的。每次通信可以看作是一个完整的通信过程,我们在通信过程中发送的数据是字符串“hello”和”stream”,大家也可以发送其它的字符串。
各位看官,关于基于AF_INET域的流套接字通信的例子咱们就说到这里。欲知后面还有什么例子,且听下回分解 。
看官们,我们在上一回中一起制作了我们的第二道佳肴是:基于AF_UNIX域的数据报套接字通信。今天,我将和大家一起制作第三道佳肴:基于AF_INET域的流套接字通信。
制作第三道佳肴的菜谱:流套接字过程。
制作第三道佳肴的食材:流套接字的接口,套接字属性,套接字地址信息。
看官们,以上的内容,我们在前面章回中都详细介绍过,如果大家忘记的话,可以参考前面的内容,重点是第一百四十七回的内容,因为这是我们的菜谱。在食材中最麻烦是套接字地址信息,大家可以参考一百五十五回中的例子。多说无益,我们通过具体的代码来演示。
服务器端的通信过程及其代码
//1.设置服务器端套接字的属性:域,类型和协议,我们使用了getaddrinfo函数; char * host = "localhost"; //using localhost IP address:127.0.0.1 char * server = "1080"; //using port 1080, it must be more then 1024 struct addrinfo hints; struct addrinfo *result; memset(&hints,0,sizeof(struct addrinfo)); result = NULL; hints.ai_flags = AI_NUMERICSERV; hints.ai_family = AF_INET; hints.ai_socktype = SOCK_STREAM; //get address info ,it has all attribute of socket res = getaddrinfo(host,server,&hints,&result); //2. 创建服务器端套接字 server_fd = socket(result->ai_family,result->ai_socktype,result->ai_protocol); //3.把服务器端的套接字和服务器的地址绑定在一起 res = bind(server_fd,result->ai_addr,result->ai_addrlen); //4.创建套接字队列,为通信做好准备,开始监听客户端发来的通信连接请求 res = listen(server_fd,2); //5.接受客户端发来的连接请求,并且获得与客户端匹配的socket client_fd = accept(server_fd,NULL,NULL); //6.通过套接字读取数据 res = read(client_fd,buf,BUF_SIZE); printf("[server] receiving data (%s) from client by socket\n",buf); //7.释放套接字,关闭通信 if(result->ai_next) freeaddrinfo(result); res = close(client_fd); res = close(server_fd);
客户端的通信过程及其代码
//1.设置客户端套接字的属性:域,类型和协议; char * host = "localhost"; //using localhost IP address:127.0.0.1 char * server = "1080"; //using port 1080, it must be more then 1024 struct addrinfo hints; struct addrinfo *result; memset(&hints,0,sizeof(struct addrinfo)); result = NULL; hints.ai_flags = AI_NUMERICSERV; hints.ai_family = AF_INET; hints.ai_socktype = SOCK_STREAM; //get address info ,it has all attribute of socket res = getaddrinfo(host,server,&hints,&result); //2.创建客户端套接字; client_fd = socket(result->ai_family,result->ai_socktype,result->ai_protocol); //3.使用客户端套接字和服务器进行连接; res = connect(client_fd,result->ai_addr,result->ai_addrlen); //4.通过套接字发送数据; printf("[client] sending data (%s )to server by socket \n",buf); res = write(client_fd,buf,sizeof(buf) ); //5.释放套接字,断开客户端与服务器端的通信; if(result->ai_next) freeaddrinfo(result); res = close(client_fd);
看官们,以上是核心代码,完整的代码放到了我的资源中,大家可以点击这里下载使用。
关于上面的代码,我做一些补充说明:
我们首先获取套接字地址的信息,然后才创建套接字,虽然与菜谱中的顺序不一致,但是这种做法是合理 的,因为我们以前创建套接字的时候,都是直接在函数中写入套接字的属性。在这里,我们使用了getaddrinfo函数的结果,这种方法可以提高代码的移植性。这种方法,也使用在了bind函数中。
我们在通信中使用了localhost主机,并且给它指定了端口号:1080。在指定端口号时,它的数值需要大于1024。因为Linux系统给小于1024的端口绑定了专门的服务。
在释放套接字的同时,我们与要释放存放套接字地址信息的链表。
与使用Unix域套接字通信的例子相比, 主要是设置套接字属性和地址的方式不同,通信过程中读取和接收数据的方式是相同的。
我们需要把服务器端的代码和客户端的代码分别进行编译,并且编译成不同的可以执行文件:
$ gcc Ex092_InetStreamSocketClient.c -o client //编译客户端 $ gcc Ex092_InetStreamSocketServer.c -o server //编译服务器端
看官们,美味佳肴做好了,我们一起来品尝下,品尝方法就是运行程序,下面是程序的运行结果,请大家参考:
$./server & //在后面运行服务器 [1] 4643 $ ./client //运行客户端 please input less then 8 chars for using. hello [client] sending data (hello )to server by socket [server] receiving data (hello) from client by socket $ ./client //再次运行客户端 please input less then 8 chars for using. stream [client] sending data (stream )to server by socket [server] receiving data (stream) from client by socket [1]+ Done ./server //服务器端运行结束
看官们,从上面的运行结果中可以看到,客户端通过套接字发送数据给服务器,而服务器通过套接字接收客户端发来的数据,这样客户端和服务器端可以通过套接字进行通信。另外,我们进行了两次通信,通信的次数可以自己控制,甚至写成无限次也是可以的。每次通信可以看作是一个完整的通信过程,我们在通信过程中发送的数据是字符串“hello”和”stream”,大家也可以发送其它的字符串。
各位看官,关于基于AF_INET域的流套接字通信的例子咱们就说到这里。欲知后面还有什么例子,且听下回分解 。
相关文章推荐
- C语言回顾与再学习
- HDU 4734-F(x)(数位DP)
- 字符串的旋转问题
- c++第六次作业
- c++第六次实验
- C++学习(一)——基本语法
- leetcode 101 Symmetric Tree C++
- C++循环队列基本操作
- C++ 智能指针(shared_ptr/weak_ptr)源码分析
- C语言《函数如何区分形参and实参》
- c++常见容器操作
- VS2010使用c++、gSOAP调用WebService 图文教程
- c++ 指向类成员函数的函数指针
- C语言实现一个简单的词法分析器
- c++输出流cout的
- 《C++ Primer》 chapter 15 TextQuery
- [c++] stack的使用
- C语言++问题
- C语言常见单链表面试题(1)
- C语言常见单链表面试题(2)