面向连接的网络应用程序分为客户端和服务器端。服务器端的执行流程一般为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函数的作用的更多相关文章

  1. javascript中bind函数的作用

    javascript的bind的作用 <!DOCTYPE html> <html> <head> <meta charset="utf-8" ...

  2. bind函数的作用

    面向连接的网络应用程序分为客户端和服务器端.服务器端的执行流程一般为4步,客户端程序相对简单,一般需要两个步骤. 服务器端执行流程4步如下: (1)调用socket函数,建立一个套接字,该套接字用于接 ...

  3. 在网络通讯中应用Protobuf

    在网络通讯中应用Protobuf Protobuf的设计非常适用于在网络通讯中的数据载体,它序列化出来的数据量少再加上以K-V的方式来存储数据,对消息的版本兼容性非常强:还有一个比较大的优点就是有着很 ...

  4. php中session_start()函数的作用

    php中session_start()函数的作用 用$_SESION之前必须要session_start()----其中之一的功能,$_SESSION是服务器端的cookie,相当一个大数组(浏览器关 ...

  5. C++中虚函数的作用和虚函数的工作原理

    1 C++中虚函数的作用和多态 虚函数: 实现类的多态性 关键字:虚函数:虚函数的作用:多态性:多态公有继承:动态联编 C++中的虚函数的作用主要是实现了多态的机制.基类定义虚函数,子类可以重写该函数 ...

  6. 网络编程api bind函数细节 select 细节

    struct sockaddr_in bindaddr; bindaddr.sin_family = AF_INET; bindaddr.sin_addr.s_addr = htonl(INADDR_ ...

  7. C++中虚函数的作用浅析

    虚函数联系到多态,多态联系到继承.所以本文中都是在继承层次上做文章.没了继承,什么都没得谈. 下面是对C++的虚函数这玩意儿的理解. 一, 什么是虚函数(如果不知道虚函数为何物,但有急切的想知道,那你 ...

  8. C++中虚函数的作用是什么?它应该怎么用呢?(转)

    虚函数联系到多态,多态联系到继承.所以本文中都是在继承层次上做文章.没了继承,什么都没得谈. 下面是对C++的虚函数这玩意儿的理解. 一, 什么是虚函数(如果不知道虚函数为何物,但有急切的想知道,那你 ...

  9. C++中虚函数的作用

    一, 什么是虚函数(如果不知道虚函数为何物,但有急切的想知道,那你就应该从这里开始) 简单地说,那些被virtual关键字修饰的成员函数,就是虚函数.虚函数的作用,用专业术语来解释就是实现多态性(Po ...

随机推荐

  1. EasyUI Calendar 日历插件,只显示年月。

    从别人的博客园搬过来的,放在这里只是为了方便自己用.已经注明原文出处,尊重别人的劳动成果. 原文地址:http://www.cnblogs.com/hmYao/p/5779463.html 此日历插件 ...

  2. 杂记(那些我还容易混淆的c和c++知识)

    1: 定义一个对象时先调用基类的构造函数.然后调用派生类的构造函数:析构的时候恰好相反:先调用派生类的析构函数.然后调用基类的析构函数.2:  多态性具体体现在运行和编译两个方面:在程序运行时的多态性 ...

  3. leetcode -50. Pow(x, n) Accepted

    前言:其实之前自己也有了解关于算法数据结构的一点内容,但是都是用相应的开发工具来写相应的代码,今天面试的时候直接leetcode来写代码,还是用的体内根深蒂固的C和Java来解的题,毕竟目前没见支持O ...

  4. C++程序设计入门(上) string类的基本用法

    string类中的函数 1. 构造 2. 追加 3. 赋值 4. 位置与清除 5. 长度与容量 6. 比较 7. 子串 8. 搜索 9. 运算符 追加字符串 string s1("Welc ...

  5. 关于DP

    关于DP 似乎摸到了门槛呢,学着学着Dijkstra突然有了感觉. 我们遍历的时候会遍历整张图的每个点每条边,然后与已知的对比大小,如果比现在方案好,就放入数组 那么,DP岂不是同样的思想? 在背包问 ...

  6. RedirectAttributes 之 IE8请求跳转失败

    1.时间真快,一晃又快冬天了,下了第一场雪.雪花漫漫,堵车悠悠. 2.这次遇到这样一个问题,就是RedirectAttributes传递数据参数,如果参数数据过大,在IE8浏览器时候会跳转不过去.其实 ...

  7. jquery 增加与删除数组元素

    1.数组元素的添加 demoArray.push(value); var demo=new Array(); var key=[4,5]; demo.push(1);//插入数字 demo.push( ...

  8. java 加载并读取Properties 文件

    1 .系统自带的application.properties  (以下代码仅供参考,不能粘贴复制) 假设application.properties文件有下面两个值: come.test.name = ...

  9. Kb Article Helper

    using System; using Microsoft.Xrm.Sdk; using Microsoft.Crm.Sdk.Messages; using Microsoft.Xrm.Sdk.Que ...

  10. 手搓一个兔子问题(分享一个C语言问题,持续更新...)

    大家好,我是小七夜,今天就不分享C语言的基础知识了,分享一个比较好玩的C语言经典例题:兔子问题 题目是这样的:说有一个穷苦人这天捉到了一只公兔子,为了能繁衍后代他又买了一只母兔子,后来兔子开始生小兔子 ...