第十篇:基于TCP的一对回射客户/服务器程序及其运行过程分析( 上 )

前言

本文将讲解一对经典的客户/服务器回射程序,感受网络编程的大致框架( 该程序稍作改装即可演变成各种提供其他服务的程序 );同时,还将对其运行过程加以分析,观察程序背后协议的执行细节,学习调试网络程序的技巧。

客户端

 1 #include    "unp.h"
 2
 3 void str_cli(FILE *fp, int sockfd);
 4
 5 int
 6 main(int argc, char **argv)
 7 {
 8     int                    sockfd;
 9     struct sockaddr_in    servaddr;
10
11     if (argc != 2)
12         err_quit("usage: tcpcli <IPaddress>");
13
14     sockfd = Socket(AF_INET, SOCK_STREAM, 0);
15
16     bzero(&servaddr, sizeof(servaddr));
17     servaddr.sin_family = AF_INET;
18     servaddr.sin_port = htons(SERV_PORT);
19     Inet_pton(AF_INET, argv[1], &servaddr.sin_addr);
20
21     Connect(sockfd, (SA *) &servaddr, sizeof(servaddr));
22
23     str_cli(stdin, sockfd);
24
25     exit(0);
26 }
27
28 /*
29  * 事务函数
30 */
31 void
32 str_cli(FILE *fp, int sockfd)
33 {
34     char    sendline[MAXLINE], recvline[MAXLINE];
35
36     // 从标准输入读取字符串( 阻塞于用户 )
37     while (Fgets(sendline, MAXLINE, fp) != NULL) {
38
39         // 往缓冲区写入字符串
40         Writen(sockfd, sendline, strlen(sendline));
41
42         // 从缓冲区读取字符串( 阻塞于服务器传回的数据 )
43         if (Readline(sockfd, recvline, MAXLINE) == 0)
44             err_quit("str_cli: server terminated prematurely");
45
46         // 读取从服务器回射的消息并在终端打印
47         Fputs(recvline, stdout);
48     }
49 }

服务器端

 1 #include    "unp.h"
 2
 3 void str_echo(int sockfd);
 4
 5 int
 6 main(int argc, char **argv)
 7 {
 8     int                    listenfd, connfd;
 9     pid_t                childpid;
10     socklen_t            clilen;
11     struct sockaddr_in    cliaddr, servaddr;
12
13     listenfd = Socket(AF_INET, SOCK_STREAM, 0);
14
15     bzero(&servaddr, sizeof(servaddr));
16     servaddr.sin_family      = AF_INET;
17     servaddr.sin_addr.s_addr = htonl(INADDR_ANY);
18     servaddr.sin_port        = htons(SERV_PORT);
19
20     Bind(listenfd, (SA *) &servaddr, sizeof(servaddr));
21
22     Listen(listenfd, LISTENQ);
23
24     for ( ; ; ) {
25         clilen = sizeof(cliaddr);
26         connfd = Accept(listenfd, (SA *) &cliaddr, &clilen);
27
28         if ( (childpid = Fork()) == 0) {    /* 子进程处理段 */
29             Close(listenfd);    /* 关闭监听套接字 */
30             str_echo(connfd);    /* 事务处理 */
31             exit(0);
32         }
33         Close(connfd);            /* 父进程关闭连接套接字 */
34     }
35 }
36
37 /*
38  * 事务处理函数
39 */
40 void
41 str_echo(int sockfd)
42 {
43     ssize_t        n;
44     char        buf[MAXLINE];
45
46 again:
47     while ( (n = read(sockfd, buf, MAXLINE)) > 0)
48         Writen(sockfd, buf, n);
49
50     if (n < 0 && errno == EINTR)
51         goto again;
52     else if (n < 0)
53         err_sys("str_echo: read error");
54 }
时间: 2024-10-24 03:26:34

第十篇:基于TCP的一对回射客户/服务器程序及其运行过程分析( 上 )的相关文章

第十一篇:基于TCP的一对回射客户/服务器程序及其运行过程分析( 下 )

执行分析 1. 打开服务器进程: 2. 执行netstat -a命令观察当前的连接状态: 第1条连接记录说明:绑定了本地主机的任意IP,端口为9877,目前处于监听状态. 3. 打开客户进程: 4. 执行netstat -a命令观察当前的连接状态,发现了两个新的连接: 以及 上面一个连接说明一个连接到服务器的连接,客户端临时端口是32818,目的端口正是先前的9877,连接状态为已建立,对应已连接套接字: 下面一个连接说明一个连接到客户端的连接,服务端端口为9877,目的端口是32818,这个连

最简单的回射客户/服务器程序、time_wait 状态

下面通过最简单的客户端/服务器程序的实例来学习socket API. echoser.c 程序的功能是从客户端读取字符然后直接回射回去. C++ Code 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 6

利用System V消息队列实现回射客户/服务器

一.介绍 在学习UNIX网络编程 卷1时,我们当时可以利用Socket套接字来实现回射客户/服务器程序,但是Socket编程是存在一些不足的,例如: 1. 服务器必须启动之时,客户端才能连上服务端,并与服务端进行通信: 2. 利用套接口描述符进行通信,必须知道对端的IP与端口. 二.相关函数介绍 下面,我们利用System V消息队列来实现进程间的通信: 首先,我们先来了解一下下面几个函数: 1. msgget: 该函数用于打开或创建消息队列,其作用相当与文件操作函数open. #include

简单回射客户/服务器

一.程序功能 (1)客户从标准输入读入一行文本行,并写给服务器: (2)服务器从网络输入读入这行文本,并回射给客户: (3)客户从网络输入读入这行回射文本,并显示在标准输出上 二.服务器程序 #include <stdio.h> #include <stdlib.h> #include <time.h> #include <errno.h> #include <string.h> #include <sys/types.h> #inc

UNIX网络编程卷1 回射客户程序 TCP客户程序设计范式

本文为senlie原创,转载请保留此地址:http://blog.csdn.net/zhengsenlie 下面我会介绍同一个使用 TCP 协议的客户端程序的几个不同版本,分别是停等版本.select 加阻塞式 I/O 版本. 非阻塞式 I/O 版本.fork 版本.线程化版本.它们都由同一个 main 函数调用来实现同一个功能,即回射程序客户端. 它从标准输入读入一行文本,写到服务器上,读取服务器对该行的回射,并把回射行写到标准输出上. 其中,非阻塞式 I/O 版本是所有版本中执行速度最快的,

UNIX网络编程笔记(4)—TCP客户/服务器程序示例

TCP客户/服务器程序示例 这一章信息量开始大起来了,粗略来看它实现了简单的TCP客户/服务器程序,里面也有一些费解的细节. 1.概述 完整的TCP客户/服务器程序示例.这个简单的例子将执行如下步骤的一个回射服务器(这里的回射服务器就是服务简单的把客户端发送的消息返回给客户): 1)客户从标准输入读入一行文本,并写给服务器 2)服务器从网络输入读入这行文本,并回射给客户 3)客户从网络输入读入这行回射文本,并显示在标准输出上 这样实际上就构成了一个全双工的TCP连接. 本章就围绕了这个简单的TC

【UNIX网络编程】TCP客户/服务器程序示例

做一个简单的回射服务器: 客户从标准输入读入一行文本,写给服务器 -> 服务器从网络输入读入这行文本,并回射给客户 -> 客户从网络输入读入这行回射文本,并显示在标准输出上 以下是我的代码(部分.h文件是由unpv13e文件夹中的.c文件改名得到) #include "../unpv13e/unp.h" #include "../unpv13e/apueerror.h" #include "../unpv13e/wrapsock.h"

【UNIX网络编程(三)】TCP客户/服务器程序示例

上一节给出了TCP网络编程的函数,这一节使用那些基本函数编写一个完成的TCP客户/服务器程序示例. 该例子执行的步骤如下: 1.客户从标准输入读入一行文本,并写给服务器. 2.服务器从网络输入读入这行文本,并回射给客户. 3.客户从网络输入读入这行回射文本,并显示在标准输出上. 用图描述如下: 编写TCP回射服务器程序如下: #include <stdio.h> #include <errno.h> #include <stdlib.h> #include <st

TCp客户/服务器程序示例

1. TCP回射服务器程序:main函数 #include "unp.h" int main(int argc, char **argv) { int listenfd, connfd; pid_t childpid; socklen_t clilen; struct sockaddr_in cliaddr, servaddr; listenfd = Socket(AF_INET, SOCK_STREAM, 0); bzero(&servaddr, sizof(servaddr