Chinaunix首页 | 论坛 | 博客
  • 博客访问: 383874
  • 博文数量: 55
  • 博客积分: 1907
  • 博客等级: 上尉
  • 技术积分: 869
  • 用 户 组: 普通用户
  • 注册时间: 2010-11-04 19:30
文章分类

全部博文(55)

文章存档

2011年(32)

2010年(23)

分类: LINUX

2011-04-28 21:34:50

简单TCP编程
----------------------------------------------------------------------------
专有名词:
    TCP: Transmission Control Protocol,传输控制协议。
    IP:  Internet Protocol,网际协议。
    ISO:International Organization for Sdandardization ,国际标准化组织。
    OSI: open systems interconnection,开放系统互连。
    HTTP: Hypertext Transfer Protocol,超文本传输协议。
    SMTP: Simple Mail Transfer Porotocol,简单邮件传输协议。
 
OSI协议模型: 应用层、表示层、会话层、传输层、网络层   、数据链路层、物理层。
网际网协议族:应用层                、TCP/TP、IPv4/IPv6、设备驱动程序和硬件。
 
    在OSI协议中顶上三层实现的是具体的网络应用(如FTP,Telnet或HTTP)的所有细节
    对通信细节了解很少,而底下四层对具体的网络应用了解不多,却处理所有的通信
    细节:发送数据、等待确认、给无序到达的数据排序、计算并验证校验和等等。顶
    上三层通常构成所谓的用户进程,而底下四层通常是由操作系统的内核提供的。
              
    客户与服务器通信是通过某个网络协议来实现的,但实际上,这样的通信通常涉及多个
    网络协议。本文主要讲的是TCP/IP协议族,也称为网际协议族。当一个客户进程与服务
    器之间使用TCP时,TCP又转而使用IP通信,IP再通过某种形式的数据链路层通信。
 
    客户->TCP->IP->数据链路层
    服务器->TCP->IP->数据链路层

编程进阶:

客户应用进程
1、创建TCP套接字
   int socket(int domain, int type, int protocol);
  
   套接字三属性:domain(域)、type(类型)、protocol(协议)   
   domain: 常用的有 AF_UNIX、AF_INET
   type:   常用的有 SOCK_STREAM
   protocol: 一般为 0
  
2、指定服务器的 IP 地址和端口
   往 struct sockaddr_in 结构中填入网际类型、服务器的IP和端口号
  
3、建立与服务器点连接
   int connect(int sockfd, const struct sockaddr *serv_addr, socklen_t addrlen);
4、读入并输出服务器点应答(与服务器通信)
 for(;;)
 {
     ......;  /* do something */
 }
5、终止程序
 
服务器应用进程
1、创建 TCP 套接字
   int socket(int domain, int type, int protocol);
2、把服务器的众所周知端口捆绑到套接字
   int bind(int sockfd, const struct sockaddr *myaddr, socklen_t addrlen);
  
3、把套接字转换成监听套接字
   int listen(int sockfd, int backlog);
4、接受客户连接,发送应答(与客户通信)
   int accept(int sockfd, struct sockaddr *cliaddr, socklen_t *addrlen);
   for(;;)
   {
       accept();
       ......;    /* do something */
   }
5、终止程序
附上UNIX网络编程随书的一个例程:
  1. //客户端:
  2. #include "unp.h"
  3. int
  4. main(int argc, char **argv)
  5. {
  6.  int sockfd, n;
  7.  char recvline[MAXLINE + 1];
  8.  struct sockaddr_in servaddr;
  9.  if (argc != 2)
  10.   err_quit("usage: a.out ");
  11.  /* 创建 TCP 套接字 */
  12.  if ( (sockfd = socket(AF_INET, SOCK_STREAM, 0)) < 0)
  13.   err_sys("socket error");
  14.  /* 指定服务器的 IP 地址和端口 */
  15.  bzero(&servaddr, sizeof(servaddr));
  16.  servaddr.sin_family = AF_INET;
  17.  servaddr.sin_port = htons(13); /* daytime server */
  18.  /* 以前使用 inet_addr 函数来将 ASCII 点分十进制数串转换成正确点格式 */
  19.  if (inet_pton(AF_INET, argv[1], &servaddr.sin_addr) <= 0)
  20.   err_quit("inet_pton error for %s", argv[1]);

  21.  /* 建立与服务器点连接 */
  22.  if (connect(sockfd, (SA *) &servaddr, sizeof(servaddr)) < 0)
  23.   err_sys("connect error");
  24.  /* 读入并输出服务器点应答 */
  25.  while ( (n = read(sockfd, recvline, MAXLINE)) > 0) {
  26.   recvline[n] = 0; /* null terminate */
  27.   if (fputs(recvline, stdout) == EOF)
  28.    err_sys("fputs error");
  29.  }
  30.  if (n < 0)
  31.   err_sys("read error");
  32.  /* 终止程序 */
  33.  exit(0);
  34. }



  35. //服务器端:
  36. #include "unp.h"
  37. #include <time.h>
  38. int
  39. main(int argc, char **argv)
  40. {
  41.  int listenfd, connfd;
  42.  struct sockaddr_in servaddr;
  43.  char buff[MAXLINE];
  44.  time_t ticks;
  45.  /* 创建 TCP 套接字 */
  46.  listenfd = Socket(AF_INET, SOCK_STREAM, 0);
  47.  /* 把服务器的众所周知端口捆绑到套接字 */
  48.  bzero(&servaddr, sizeof(servaddr));
  49.  servaddr.sin_family = AF_INET;
  50.  servaddr.sin_addr.s_addr = htonl(INADDR_ANY);
  51.  servaddr.sin_port = htons(13); /* daytime server */
  52.  Bind(listenfd, (SA *) &servaddr, sizeof(servaddr));
  53.  /* 把套接字转换成监听套接字 */
  54.  Listen(listenfd, LISTENQ);

  55.  /* 接受客户连接,发送应答 */
  56.  for ( ; ; ) {
  57.   fprintf(stdout, "the daytime server is waiting for now !");
  58.   /* 已连接描述符 connfd 用于与新近连接点那个客户通信 */
  59.   connfd = Accept(listenfd, (SA *) NULL, NULL);
  60.         ticks = time(NULL);
  61.         snprintf(buff, sizeof(buff), "%.24s\r\n", ctime(&ticks));
  62.         Write(connfd, buff, strlen(buff));
  63.   /* 终止连接 */
  64.   Close(connfd);
  65.  }
  66. }
 
阅读(2028) | 评论(0) | 转发(1) |
给主人留下些什么吧!~~