Linux系统下socket通信注意之bind函数
2015-05-21 22:51
197 查看
一般我们在测试C/S程序的时候,为了方便。一般客户端连接服务器的时候,我们会不注意客户端的ip与端口,我们只关注的是服务器端的ip与端口,这样我们就可以与server通信。
在tcp/ip协议中,我们看到TCP或者UDP数据帧,都含有源地址、源端口与目的地址、目的端口。在socket编程中,创建一个socket句柄,都会有本地的一个IP与端口对应,这个就是源地址与源端口。如果我们在程序中不指定这个源地址与源端口会怎么样呢?这里指定的时候我们采用bind函数进行绑定地址与端口。
如果一个TCP客户端或者服务器没有调用bind进行绑定,因为在调用socket函数创建套接字的时候,内核还没有为套接字分配地址及其端口,当调用connect或者listen函数的时候,内核就要为相应的套接字选择一个临时的端口与地址。
在讨论bind函数之前,需要对网络地址端口格式进行了解:
通用的网络地址标识为sockaddr,为了使不同格式的地址能够传入到套接字函数,地址需要被强制转换成sockaddr类型。其结构如下:
Internet的地址定义在<netinet/in.h>,在IPV4因特网中(AF_INET)中,套接字的地址结构如下:
下面展示一个客户端绑定本地地址与端口的实例:
在tcp/ip协议中,我们看到TCP或者UDP数据帧,都含有源地址、源端口与目的地址、目的端口。在socket编程中,创建一个socket句柄,都会有本地的一个IP与端口对应,这个就是源地址与源端口。如果我们在程序中不指定这个源地址与源端口会怎么样呢?这里指定的时候我们采用bind函数进行绑定地址与端口。
如果一个TCP客户端或者服务器没有调用bind进行绑定,因为在调用socket函数创建套接字的时候,内核还没有为套接字分配地址及其端口,当调用connect或者listen函数的时候,内核就要为相应的套接字选择一个临时的端口与地址。
在讨论bind函数之前,需要对网络地址端口格式进行了解:
通用的网络地址标识为sockaddr,为了使不同格式的地址能够传入到套接字函数,地址需要被强制转换成sockaddr类型。其结构如下:
struct sockaddr{ sa_family_t sa_family; char sa_data[]; ...... }套接字可以实现添加额外成员到sa_data中,Linux中此成员为sa_data[14]。
Internet的地址定义在<netinet/in.h>,在IPV4因特网中(AF_INET)中,套接字的地址结构如下:
struct sockaddr_in{ sa_family_t sin_family; in_port_t sin_port; struct in_addr sin_addr; } struct in_addr{ in_addr_t s_addr; }然后bind函数的原型如下:
int bind(int sockfd,const struct sockaddr *addr,socklen_t len);成功调用返回0,出错返回-1;
下面展示一个客户端绑定本地地址与端口的实例:
/*server ip and port*/ struct sockaddr_in servaddr; bzero(&servaddr,sizeof(servaddr)); servaddr.sin_family = AF_INET; servaddr.sin_addr.s_addr = inet_addr(argv[1]); servaddr.sin_port = htons(atoi(argv[2])); /*local ip and port*/ struct sockaddr_in cltaddr; bzero(&cltaddr,sizeof(cltaddr)); cltaddr.sin_family = AF_INET; cltaddr.sin_addr.s_addr = inet_addr(argv[3]); cltaddr.sin_port = htons(atoi(argv[4])); /*create socket*/ sockfd =socket(AF_INET,SOCK_STREAM,0); if(sockfd<0){ printf("create socket error...\n"); exit(1); } int reuse = 1; setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, &reuse, sizeof(int)); if((bind(sockfd,(struct sockaddr*)&cltaddr,sizeof(cltaddr)))<0){ printf("can not bind....\n"); exit(1); }此例子中,cltaddr代表需要绑定的本地地址信息。
相关文章推荐
- socket 通信心得以及几个自己开发写的可复用函数 perl
- socket通信中的几个函数--accept(),send(),recv()
- Java Socket 通信中传递Object对象注意的问题
- C/C++ socket编程教程之五:使用bind()和connect()函数
- socket bind函数
- 网络编程socket之bind函数
- Flash Socket 和 Erlang Socket 通信的注意事项
- socket 通信关于bind那点事
- c++中Socket通信函数之WSAStartup
- linux网络编程常用函数详解与实例(socket-->bind-->listen-->accept)
- (笔记)Linux Socket通信:bind: Address already in use
- qwebsocket使用wss通信时的应注意的问题
- 网络编程socket之bind函数
- socket编程注意的地方---bind socket error: Address already in use
- linux网络编程常用函数详解与实例(socket-->bind-->listen-->accept)
- c++中Socket通信函数之select
- socket通信常用的函数
- SOCKET中send和recv函数工作原理与注意点
- Socket:java与C之间的文件传送<3>(JAVA与C通信需要注意的地方)
- socket 通信心得以及几个自己开发写的可复用函数 perl