第四章 基本tcp 套接口编程

注意区分AF_XXX 和PF_XXX,AF代表address family, PF代表protocol family。

1 socket 函数

2 connect 函数

3 bind 函数

4 listen 函数

注:主动、被动 与 服务器、客户端没有明确的对应关系
linux中定义backlog为 完成队列的最大个数
5 accept 函数
5 getsockname和getpeername的用法及实例
getsockname和getpeername

#include <sys/socket.h>
int getsockname(int sockfd, struct sockaddr *localaddr, socklen_t *addrlen);
int getpeername(int sockfd, struct sockaddr *peeraddr, socklen_t *addrlen);
返回:0—OK,-1—出错。

getsockname函数返回与套接口关联的本地协议地址。

getpeername函数返回与套接口关联的远程协议地址。

addrlen是值-结果参数。

使用场合:

  • 在不调用bind的TCP客户,当connect成功返回后,getsockname返回分配给此连接的本地IP地址和本地端口号;
  • 在以端口号为0调用bind后,使用getsockname返回内核分配的本地端口号;
  • getsockname可用来获取某套接口的地址族;
  • 在捆绑了通配IP地址的TCP服务器上,当连接建立后,可以使用getsockname获得分配给此连接的本地IP地址;
  • 当一个服务器调用exec启动后,他获得客户身份的唯一途径是调用getpeername函数。
  • 服务器code:
 #include    "unp.h"

 int
main(int argc, char ** argv)
{
int listenfd,connfd;
struct sockaddr_in servaddr;
pid_t pid;
char temp[]; listenfd = Socket(AF_INET, SOCK_STREAM, );
bzero(&servaddr, sizeof(servaddr));
servaddr.sin_family = AF_INET;
servaddr.sin_addr.s_addr = htonl(INADDR_ANY);
servaddr.sin_port = htons();
Bind(listenfd, (SA *)&servaddr, sizeof(servaddr));
Listen(listenfd, LISTENQ);
for( ; ; )
{
struct sockaddr_in local;
connfd = Accept(listenfd, (SA *)NULL, NULL);
if((pid = fork()) == )
{
Close(listenfd);struct sockaddr_in serv, guest;
char serv_ip[];
char guest_ip[];
socklen_t serv_len = sizeof(serv);
socklen_t guest_len = sizeof(guest);
getsockname(connfd, (struct sockaddr *)&serv, &serv_len);
getpeername(connfd, (struct sockaddr *)&guest, &guest_len);
Inet_ntop(AF_INET, &serv.sin_addr, serv_ip, sizeof(serv_ip));
Inet_ntop(AF_INET, &guest.sin_addr, guest_ip, sizeof(guest_ip));
printf("host %s:%d guest %s:%d\n", serv_ip, ntohs(serv.sin_port), guest_ip, ntohs(guest.sin_port));
char buf[] = "hello world";
Write(connfd, buf, strlen(buf));
Close(connfd);
exit();
}
Close(connfd);
}
}

client code

 #include "unp.h"
#define DEST_IP "127.0.0.1" int
main(int argc, char ** argv)
{
int sockfd, n;
char buf[];
char serv_ip[], guest_ip[];
struct sockaddr_in servaddr; sockfd = Socket(AF_INET, SOCK_STREAM, );
bzero(&servaddr, sizeof(struct sockaddr_in));
servaddr.sin_family = AF_INET;
servaddr.sin_port = htons(); Inet_pton(AF_INET, DEST_IP, &servaddr.sin_addr);
Connect(sockfd, (SA *)&servaddr, sizeof(servaddr)); struct sockaddr_in serv, guest;
socklen_t serv_len = sizeof(serv);
socklen_t guest_len = sizeof(guest); getsockname(sockfd, (SA *)&guest, &guest_len);
getpeername(sockfd, (SA *)&serv, &serv_len); Inet_ntop(AF_INET, &guest.sin_addr, guest_ip, sizeof(guest_ip));
Inet_ntop(AF_INET, &serv.sin_addr, serv_ip, sizeof(serv_ip)); printf("host %s:%d, guest %s:%d\n", serv_ip, ntohs(serv.sin_port), guest_ip, ntohs(guest.sin_port)); n = Read(sockfd, buf, );
buf[n] = '\0';
printf("%s\n", buf);
Close(sockfd);
exit();
}

TCP

对于服务器来说,在bind以后就可以调用getsockname来获取本地地址和端口,虽然这没有什么太多的意义。getpeername只有在链接建立以后才调用,否则不能正确获得对方地址和端口,所以他的参数描述字一般是链接描述字而非监听套接口描述字。

对于客户端来说,在调用socket时候内核还不会分配IP和端口,此时调用getsockname不会获得正确的端口和地址(当然链接没建立更不可能调用getpeername),当然如果调用了bind 以后可以使用getsockname。想要正确的到对方地址(一般客户端不需要这个功能),则必须在链接建立以后,同样链接建立以后,此时客户端地址和端口就已经被指定,此时是调用getsockname的时机。

CP状态图:
 
 

Unix 网络编程 读书笔记3的更多相关文章

  1. UNIX网络编程--读书笔记

    会集中这段时间写UNIX网络编程这本书的读书笔记,准备读三本,这一系类的文章会不断更新,一直会持续一个月多,每篇的前半部分是书中讲述的内容,每篇文章的后半部分是自己的心得体会,文章中的红色内容是很重要 ...

  2. UNIX网络编程读书笔记:简介

    认知套接口编程接口 理解原始套接口(raw socket)的概念   值得注意的是,客户和服务器是典型的用户进程,而TCP和IP协议则通常是系统内核协议栈的一部分. 上图中在TCP和UDP之间留有间隙 ...

  3. Unix 网络编程 读书笔记1

    第一章: C/C++语言提供两种不同的编程模式:IPL32和PL64.► IPL32 ● 表示integer/pointer/long三种数据类型是32位(4个字节),在这种模式下,提供32位的地址空 ...

  4. UNIX网络编程读书笔记:原始套接口

    概述 应用程序可以绕过传输层而直接使用IPv4和IPv6,这称为原始套接口(raw socket).http://www.cnblogs.com/nufangrensheng/p/3583435.ht ...

  5. UNIX网络编程读书笔记:套接口选项

    概述 有很多方法来获取和设置影响套接口的选项: getsockopt和setsockopt函数 fcntl函数 ioctl函数 getsockopt和setsockopt函数 这两个函数仅用于套接口. ...

  6. UNIX网络编程读书笔记:I/O模型(阻塞、非阻塞、I/O复用、信号驱动、异步)

    I/O模型 UNIX下可用的5种I/O模型: (1)阻塞I/O (2)非阻塞I/O (3)I/O复用(select和poll) (4)信号驱动I/O(SIGIO) (5)异步I/O 对于一个套接口上的 ...

  7. Unix 网络编程 读书笔记2

    第三章 套接字编程简介 每一个 Socket 都用一个半相关描述:{协议,本地地址,本地端口}一个完整的 Socket 则用一个相关描述{协议,本地地址,本地端口,远程地址,远程端口}每一个 Sock ...

  8. UNIX网络编程读书笔记:UNIX域协议

    概述 UNIX域协议并不是一个实际的协议族,而是在单个主机上执行客户/服务器通信的一种方法,所用API与在不同主机上执行客户/服务器通信所用的API(套接口API)相同.UNIX域协议可视为进程间通信 ...

  9. UNIX网络编程读书笔记:基本TCP套接口编程

    编写一个完整的TCP客户和服务器程序所需要的基本套接口函数: 1.socket函数(客户端.服务器端都必须调用) 参数family指明协议族(family),该参数也往往被称为协议域(domain). ...

  10. UNIX网络编程读书笔记:辅助数据

    辅助数据(ancillary data)可通过调用sendmsg和recvmsg这两个函数,使用msghdr结构中的msg_control和msg_controllen这两个成员发送和接收. 辅助数据 ...

随机推荐

  1. Node.js modules you should know about: request

    Hey everyone! This is the fourth post in my new node.js modules you should know about article series ...

  2. IIS与Asp.net

    一.IIS 1.绑定 为了将特定的请求映射到相应的网站,IIS允许我们配置“绑定”.所谓“绑定”就是将一个特定的地址.端口号和HTTP主机名对应到特定的网站. IIS7添加绑定的代码如下图所示: 在I ...

  3. java基础学习总结——开篇

    java是我学习的第一门编程语言,当初学习java基础的时候下了不少功夫,趁着这段时间找工作之际,好好整理一下以前学习java基础时记录的笔记,当作是对java基础学习的一个总结吧,将每一个java的 ...

  4. 转 iOS获取软键盘的高度

    - (void)viewDidLoad { [super viewDidLoad]; //增加监听,当键盘出现或改变时收出消息 [[NSNotificationCenter defaultCenter ...

  5. kafka分区原理图

    一个Topic的多个分区,被分布在kafka集群中的多个server上.每一个分区都有一个server为"leader";leader负责全部的读写操作,假设leader失效,那么 ...

  6. 为Eclipse添加C/C++开发工具

    如果你是一个C / C ++开发人员,正在为你的工作寻找一款开源的IDE工具,你可以考虑基于Eclipse的IDE. Eclipse中拥有一个可扩展的插件系统定制让你轻松的来定制你的IDE,它可以支持 ...

  7. 如何高效把一字节的位对换, bit0和bit7,bit1和bit6,以此类推.

    #include<stdio.h> #include<stdlib.h> //异或法 unsigned char byteReverse(unsigned char val) ...

  8. 【BZOJ】【1091】【SCOI2003】切割多边形

    计算几何+枚举 我比较傻逼……一开始想了个贪心,就是这样:

  9. Objective-C:内存管理的小结

    内存管理: 1.OC的对象都是分配在堆里的      Perosn *person  = [[Person alloc]init];      Person *person       //指针类型的 ...

  10. max-sum-of-sub-matrix-no-larger-than-k

    根据上一篇文章提到的参考文档: https://leetcode.com/discuss/109749/accepted-c-codes-with-explanation-and-references ...