网络通讯中 bind函数的作用
面向连接的网络应用程序分为客户端和服务器端。服务器端的执行流程一般为4步,客户端程序相对简单,一般需要两个步骤。
服务器端执行流程4步如下:
(1)调用socket函数,建立一个套接字,该套接字用于接下来的网络通信。
(2)调用bind函数,将该套接字绑定到一个地址,并制定一个端口号,
(3)调用listen函数,使用该套接字监听连接请求
(4)当请求来到时,调用accept函数复制该套接字处理请求
客户端执行流程2步如下:
(1)调用socket函数,创建一个套接字
(2)调用connect函数使用该套接字与服务器进行连接
服务器端和客户端程序的显著区别在于客户端程序不需要调用bind函数,bind函数的作用是将套接字绑定一个IP地址和端口号,因为这两个元素可以在网络环境中唯一地址表示一个进程。如果套接字没有使用bind函数绑定地址和端口,那么调用listen函数和connect函数的时候内核会自动为套接字绑定。由此可知,如果没有使用bind函数,调用listen函数和connect函数的时候内核会自动为套接字绑定。看起来好像bind函数是多余的,但事实并不是这样。
我们先来看看listen函数和connect是怎么绑定套接字的,connect函数绑定套接字的时候使用的是一个设置好的地址结构(sockaddr_in)作为参数,结构中指定了服务器的地址和需要通信的端口号。但是listen函数没有这个参数,多以listen函数不能够使用设置好的地址结构,只能由系统设置IP地址和端口号。也就是说在服务器端,如果不使用bind函数的话,创建套接字时使用的是当前系统中空闲端口的套接字。
这样的话,服务器端的程序不关心客户端的IP地址,也就说是对应的端口号是内核临时指派的一个端口,是随机的,每次执行服务器程序的时候,使用的都是不同的端口。但是在客户端是需要指定通信的服务器的端口的,如果不使用bind函数,每次的端口是随机的话,那么每次重启服务程序之后都要对客户端的程序进行调整,这样做不仅不合理,而且工作量很大,因此在服务器端bind函数作用非常重要。
下面是一个使用bind函数的服务器端程序,可以作为参考理解。

#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <stdlib.h>
#include <strings.h>
#include <ctype.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#define MAX_LINE 100 int main(void)
{
struct sockaddr_in sin;
struct sockaddr_in cin;
int l_fd;
int c_fd;
socklen_t len;
char buf[MAX_LINE];
char addr_p[INET_ADDRSTRLEN];
int port = 8000;
int n;
bzero(&sin, sizeof(sin));
sin.sin_family = AF_INET;
sin.sin_addr.s_addr = INADDR_ANY;
sin.sin_port = htons(port);
/*创立套接字,使用TCP协议*/
if((l_fd = socket(AF_INET, SOCK_STREAM, 0)) == -1)
{
perror("fail to creat socket");
exit(1);
}
/*将地址和套节字绑定*/
if(bind(l_fd, (struct sockaddr *) &sin, sizeof(sin)) == -1)
{
perror("fail to bind");
exit(1);
}
/*开始监听连接请求*/
if(listen(l_fd, 10) == -1)
{
perror("fail to listren");
exit(1);
}
printf("waiting...\n");
while(1)
{
/*接受连接请求,从此函数中返回后就可以开始通信了*/
if((c_fd = accept(l_fd, (struct sockaddr *) &cin, &len)) == -1)
{
perror("fail to accept");
exit(1);
}
/*调用recv函数读取客户端传来的信息,不设置任何特殊的标志*/
n = recv(c_fd, buf, MAX_LINE, 0);
if(n = -1)
{
perror("fail to receive");
exit(1);
}
else if(n == 0)
{
printf("the connect has been closed\n ");
close(c_fd);
continue;
}
/*将客户端地址转换为字符串*/
inet_ntop(AF_INET, &cin.sin_addr, addr_p, sizeof(addr_p));
printf("client IP is %s, port is %s \n", addr_p, ntohs(cin.sin_port));
printf("connect is : %s\n", buf);
n = strlen(buf);
sprintf(buf, "%d", n);
/*使用send函数将转换后的字符串发送给客户端,不设置任何特殊的标志*/
n = send(c_fd, buf, strlen(buf) + 1, 0);
if(n == -1)
{
perror("fail to send");
exit(1);
}
if(cloes(c_fd) == -1)
{
perror("fail to close");
exit(1);
}
}
return 0;
}
网络通讯中 bind函数的作用的更多相关文章
- javascript中bind函数的作用
javascript的bind的作用 <!DOCTYPE html> <html> <head> <meta charset="utf-8" ...
- bind函数的作用
面向连接的网络应用程序分为客户端和服务器端.服务器端的执行流程一般为4步,客户端程序相对简单,一般需要两个步骤. 服务器端执行流程4步如下: (1)调用socket函数,建立一个套接字,该套接字用于接 ...
- 在网络通讯中应用Protobuf
在网络通讯中应用Protobuf Protobuf的设计非常适用于在网络通讯中的数据载体,它序列化出来的数据量少再加上以K-V的方式来存储数据,对消息的版本兼容性非常强:还有一个比较大的优点就是有着很 ...
- php中session_start()函数的作用
php中session_start()函数的作用 用$_SESION之前必须要session_start()----其中之一的功能,$_SESSION是服务器端的cookie,相当一个大数组(浏览器关 ...
- C++中虚函数的作用和虚函数的工作原理
1 C++中虚函数的作用和多态 虚函数: 实现类的多态性 关键字:虚函数:虚函数的作用:多态性:多态公有继承:动态联编 C++中的虚函数的作用主要是实现了多态的机制.基类定义虚函数,子类可以重写该函数 ...
- 网络编程api bind函数细节 select 细节
struct sockaddr_in bindaddr; bindaddr.sin_family = AF_INET; bindaddr.sin_addr.s_addr = htonl(INADDR_ ...
- C++中虚函数的作用浅析
虚函数联系到多态,多态联系到继承.所以本文中都是在继承层次上做文章.没了继承,什么都没得谈. 下面是对C++的虚函数这玩意儿的理解. 一, 什么是虚函数(如果不知道虚函数为何物,但有急切的想知道,那你 ...
- C++中虚函数的作用是什么?它应该怎么用呢?(转)
虚函数联系到多态,多态联系到继承.所以本文中都是在继承层次上做文章.没了继承,什么都没得谈. 下面是对C++的虚函数这玩意儿的理解. 一, 什么是虚函数(如果不知道虚函数为何物,但有急切的想知道,那你 ...
- C++中虚函数的作用
一, 什么是虚函数(如果不知道虚函数为何物,但有急切的想知道,那你就应该从这里开始) 简单地说,那些被virtual关键字修饰的成员函数,就是虚函数.虚函数的作用,用专业术语来解释就是实现多态性(Po ...
随机推荐
- EasyUI Calendar 日历插件,只显示年月。
从别人的博客园搬过来的,放在这里只是为了方便自己用.已经注明原文出处,尊重别人的劳动成果. 原文地址:http://www.cnblogs.com/hmYao/p/5779463.html 此日历插件 ...
- 杂记(那些我还容易混淆的c和c++知识)
1: 定义一个对象时先调用基类的构造函数.然后调用派生类的构造函数:析构的时候恰好相反:先调用派生类的析构函数.然后调用基类的析构函数.2: 多态性具体体现在运行和编译两个方面:在程序运行时的多态性 ...
- leetcode -50. Pow(x, n) Accepted
前言:其实之前自己也有了解关于算法数据结构的一点内容,但是都是用相应的开发工具来写相应的代码,今天面试的时候直接leetcode来写代码,还是用的体内根深蒂固的C和Java来解的题,毕竟目前没见支持O ...
- C++程序设计入门(上) string类的基本用法
string类中的函数 1. 构造 2. 追加 3. 赋值 4. 位置与清除 5. 长度与容量 6. 比较 7. 子串 8. 搜索 9. 运算符 追加字符串 string s1("Welc ...
- 关于DP
关于DP 似乎摸到了门槛呢,学着学着Dijkstra突然有了感觉. 我们遍历的时候会遍历整张图的每个点每条边,然后与已知的对比大小,如果比现在方案好,就放入数组 那么,DP岂不是同样的思想? 在背包问 ...
- RedirectAttributes 之 IE8请求跳转失败
1.时间真快,一晃又快冬天了,下了第一场雪.雪花漫漫,堵车悠悠. 2.这次遇到这样一个问题,就是RedirectAttributes传递数据参数,如果参数数据过大,在IE8浏览器时候会跳转不过去.其实 ...
- jquery 增加与删除数组元素
1.数组元素的添加 demoArray.push(value); var demo=new Array(); var key=[4,5]; demo.push(1);//插入数字 demo.push( ...
- java 加载并读取Properties 文件
1 .系统自带的application.properties (以下代码仅供参考,不能粘贴复制) 假设application.properties文件有下面两个值: come.test.name = ...
- Kb Article Helper
using System; using Microsoft.Xrm.Sdk; using Microsoft.Crm.Sdk.Messages; using Microsoft.Xrm.Sdk.Que ...
- 手搓一个兔子问题(分享一个C语言问题,持续更新...)
大家好,我是小七夜,今天就不分享C语言的基础知识了,分享一个比较好玩的C语言经典例题:兔子问题 题目是这样的:说有一个穷苦人这天捉到了一只公兔子,为了能繁衍后代他又买了一只母兔子,后来兔子开始生小兔子 ...