Unix网络编程 4- TCP编程_第1页
Unix网络编程 4- TCP编程_第2页
Unix网络编程 4- TCP编程_第3页
Unix网络编程 4- TCP编程_第4页
Unix网络编程 4- TCP编程_第5页
已阅读5页,还剩27页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

1、Unix网络编程,第四讲 TCP socket 编程,Unix和TCP/network的关系,TCP的特点 协议特点 实现特点 编程特点,TCP Sockets Programming,创建一个 被动模式的 (server) socket. 建立TCP 连接. 发送/接收 数据. 关闭连接.,TCP C/S 编程,创建一个 TCP socket,int socket(int family,int type,int proto); int sock; sock = socket(PF_INET, SOCK_STREAM, 0); if (sock0) /* ERROR */ ,绑定到有名地址,i

2、nt mysock; struct sockaddr_in myaddr; mysock = socket(PF_INET,SOCK_STREAM,0); myaddr.sin_family = AF_INET; myaddr.sin_port = htons( 80 ); myaddr.sin_addr = htonl( INADDR_ANY ); bind(mysock, (sockaddr *) ,建立被动模式的 TCP socket,被动模式: 地址已经确定. 告诉内核接受到我(应用程序)的连接请求. 3-way handshake 告诉内核为我(应用程序)将到来的连接保存(排队)起来

3、.,listen(),int listen(int sockfd, int backlog); sockfd TCP socket (已经绑定地址) backlog 内核为应用程序缓冲到来连接的数目. listen() returns -1 on error otherwise 0.,listening socket的两个队列,接受连接请求 accept(),一旦调用了 listen(), 内核将替我们将带来的连接进行排队缓冲 处理三次握手 将多个连接排队缓冲. 当我们的应用程序可以处理新的连接时, 我们需要向内核请求下一个连接.,accept(),int accept( int sockfd

4、, struct sockaddr* cliaddr, socklen_t *addrlen); sockfd 是被动模式的 TCP socket. cliaddr 指针,指向一个已分配好的空间. 返回客户地址. addrlen 是一个 value-result 参数 必须设置为 cliaddr 的空间大小 返回时, 将被设置为使用 cliaddr 的空间大小.,accept() 返回值,accept() 返回 一个 新的 socket 描述符 -1 错误. 一旦 accept 返回一个新的 socket 描述符, 真正的数据 I/O 就可以进行了(在新的 socket 上 read() 和

5、write() ).,read, write,socket 的 read() and write()操作和普通文件的有所不同!,fread, fwrite,缓冲的几种形式 全缓冲 行缓冲 无缓冲 标准输入、标准输出和标准出错 stdin, full buffered, line buffered if a tty stdout, full buffered, line buffered if a tty stderr, no buffered,终结一个 TCP 连接,连接的任意一方可以执行 close() 系统调用. 和普通文件的close() 一样,如果一个文件的引用数超过1,那么实际上该连

6、接没有被终结; 如果另外一端关闭了连接, 并且本端没有缓冲数据, 那么从TCP socket读操作会返回 0 并指示 EOF.,Client Code,TCP 客户程序可以调用 connect() : 负责建立客户程序 socket 的端地址. 没有必要先调用 bind, 内核将负责给 socket 分配一个本地端地址 (TCP 端口, IP 地址). 试图和指定的服务器建立 TCP 连接. 三次握手,connect(),int connect( int sockfd, const struct sockaddr *server, socklen_t addrlen); sockfd 是一个创

7、建好的 TCP socket. server 中有服务器的地址 (IP 地址和 TCP 端口号) connect() 成功返回 0, 错误返回 -1,从 TCP socket 读,int read( int fd, char *buf, int max); 缺省情况下 read() 将阻塞一直到有数据为止. 从一个 TCP socket 一次 read() 操作的返回字节数可能 max. 你甚至得准备着一次只读取到 1 个字节 的情况 !,向一个 TCP socket 写入,int write( int fd, char *buf, int num); 一次 write() 操作可能真正写入的

8、字节数目少于 num (如果是 nonblocking socket 的话). 书中有 readn(), writen() 和 readline() 等例程.,几个有用的例程,readn,1 #include unp.h 2 ssize_t /* Read n bytes from a descriptor. */ 3 readn(int fd, void *vptr, size_t n) 4 5 size_t nleft; 6 ssize_t nread; 7 char *ptr; 8 ptr = vptr; 9 nleft = n; 10 while (nleft 0) 11 if ( (

9、nread = read(fd, ptr, nleft) = 0 */ 22 ,writen,1 #include unp.h 2 ssize_t /* Write n bytes to a descriptor. */ 3 writen(int fd, const void *vptr, size_t n) 4 5 size_t nleft; 6 ssize_t nwritten; 7 const char *ptr; 8 ptr = vptr; 9 nleft = n; 10 while (nleft 0) 11 if ( (nwritten = write(fd, ptr, nleft)

10、 = 0) 12 if (nwritten 0 21 ,readline,1 #include unp.h 3 ssize_t /* PAINFULLY SLOW VERSION - example only */ 4 readline(int fd, void *vptr, size_t maxlen) 5 6 ssize_t n, rc; 7 char c, *ptr; 8 ptr = vptr; 9 for (n = 1; n maxlen; n+) 10 again: 11 if ( (rc = read(fd, 26 ,类比人际关系,为了搞好人际关系: 你需要 主动做自我介绍. 你需

11、要 学会开放的接受别人. 你需要 主动和别人建立联系. 你需要学会 别人给什么就接受什么,而不是你要什么别人给你什么. 你需要 当问题出现时及时处理好关系.,bind(),accept(),connect(),检查错误,read 可能只有 1 byte,一个TCP应用的例子,echo client 从标准输入读取一行文字,发给 server. server 从网络读取输入,将读取到的一行文字返回给 client. client 读取反射回来的文字行,打印到标准输出.,server,1 #include unp.h 2 int main(int argc, char *argv) 4 5 int

12、 listenfd, connfd; 6 pid_t childpid; 7 socklen_t clilen; 8 struct sockaddr_in cliaddr, servaddr; 9 listenfd = Socket (AF_INET, SOCK_STREAM, 0); 10 bzero( /* parent closes connected socket */ 25 26 ,1 #include unp.h 2 void str_echo(int sockfd) 4 5 ssize_t n; 6 char bufMAXLINE; 7 again: 8 while ( (n =

13、 read(sockfd, buf, MAXLINE) 0) 9 Writen(sockfd, buf, n); 10 if (n 0 14 ,Echo client,1 #include unp.h 2 int main(int argc, char *argv) 4 5 int sockfd; 6 struct sockaddr_in servaddr; 7 if (argc != 2) 8 err_quit(usage: tcpcli ); 9 sockfd = Socket(AF_INET, SOCK_STREAM, 0); 10 bzero( 17 ,str_cli() 函数,1 #

14、include unp.h 2 void str_cli(FILE *fp, int sockfd) 4 5 char sendlineMAXLINE, recvlineMAXLINE; 6 while (Fgets(sendline, MAXLINE, fp) != NULL) 7 Writen(sockfd, sendline, strlen (sendline); 8 if (Readline(sockfd, recvline, MAXLINE) = 0) 9 err_quit(str_cli: server terminated prematurely); 10 Fputs(recvl

15、ine, stdout); 11 12 ,测试,linux % tcpserv01 & linux % netstat -a Active Internet connections (servers and established) Proto Recv-Q Send-Q Local Address Foreign Address State tcp 0 0 *:9877 *:* LISTEN linux % netstat -a Active Internet connections (servers and established) Proto Recv-Q Send-Q Local Ad

16、dress Foreign Address State tcp 0 0 *:9877 *:* LISTEN,测试,linux % tcpcli01 127.0.0.1 linux % netstat -a Active Internet connections (servers and established) Proto Recv-Q Send-Q Local Address Foreign Address State tcp 0 0 local host:9877 localhost:42758 ESTABLISHED tcp 0 0 local host:42758 localhost:

17、9877 ESTABLISHED tcp 0 0 *:9877 *:* LISTEN linux % ps -t pts/6 -o pid,ppid,tty,stat,args,wchan PID PPID TT STAT COMMAND WCHAN 22038 22036 pts/6 S -bash wait4 17870 22038 pts/6 S ./tcpserv01 wait_for_connect 19315 17870 pts/6 S ./tcpserv01 tcp_data_wait 19314 22038 pts/6 S ./tcpcli01 127.0 read_chan,测试,linux % tcpcli01 127.0.0.1 hello, world hello, world good bye good bye D Control-D is our terminal EOF character linux % netstat -a | grep 9877 tcp 0 0 *:

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论