简单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网络编程随书的一个例程:
- //客户端:
- #include "unp.h"
- int
- main(int argc, char **argv)
- {
- int sockfd, n;
- char recvline[MAXLINE + 1];
- struct sockaddr_in servaddr;
- if (argc != 2)
- err_quit("usage: a.out ");
- /* 创建 TCP 套接字 */
- if ( (sockfd = socket(AF_INET, SOCK_STREAM, 0)) < 0)
- err_sys("socket error");
- /* 指定服务器的 IP 地址和端口 */
- bzero(&servaddr, sizeof(servaddr));
- servaddr.sin_family = AF_INET;
- servaddr.sin_port = htons(13); /* daytime server */
- /* 以前使用 inet_addr 函数来将 ASCII 点分十进制数串转换成正确点格式 */
- if (inet_pton(AF_INET, argv[1], &servaddr.sin_addr) <= 0)
- err_quit("inet_pton error for %s", argv[1]);
- /* 建立与服务器点连接 */
- if (connect(sockfd, (SA *) &servaddr, sizeof(servaddr)) < 0)
- err_sys("connect error");
- /* 读入并输出服务器点应答 */
- while ( (n = read(sockfd, recvline, MAXLINE)) > 0) {
- recvline[n] = 0; /* null terminate */
- if (fputs(recvline, stdout) == EOF)
- err_sys("fputs error");
- }
- if (n < 0)
- err_sys("read error");
- /* 终止程序 */
- exit(0);
- }
- //服务器端:
- #include "unp.h"
- #include <time.h>
- int
- main(int argc, char **argv)
- {
- int listenfd, connfd;
- struct sockaddr_in servaddr;
- char buff[MAXLINE];
- time_t ticks;
- /* 创建 TCP 套接字 */
- listenfd = Socket(AF_INET, SOCK_STREAM, 0);
- /* 把服务器的众所周知端口捆绑到套接字 */
- bzero(&servaddr, sizeof(servaddr));
- servaddr.sin_family = AF_INET;
- servaddr.sin_addr.s_addr = htonl(INADDR_ANY);
- servaddr.sin_port = htons(13); /* daytime server */
- Bind(listenfd, (SA *) &servaddr, sizeof(servaddr));
- /* 把套接字转换成监听套接字 */
- Listen(listenfd, LISTENQ);
- /* 接受客户连接,发送应答 */
- for ( ; ; ) {
- fprintf(stdout, "the daytime server is waiting for now !");
- /* 已连接描述符 connfd 用于与新近连接点那个客户通信 */
- connfd = Accept(listenfd, (SA *) NULL, NULL);
- ticks = time(NULL);
- snprintf(buff, sizeof(buff), "%.24s\r\n", ctime(&ticks));
- Write(connfd, buff, strlen(buff));
- /* 终止连接 */
- Close(connfd);
- }
- }
阅读(2074) | 评论(0) | 转发(1) |