学习unix网络编程第一章

文章目录

  • 1.创建TCP套接字
  • 2.指定服务器的IP地址和端口
    • 2.1htons()函数
    • 2.2新型网路地址转化函数inet_pton和inet_ntop
  • 3.建立与服务器的连接
  • 4.读入并输出服务器的应答
  • 5.错误处理:包裹函数
  • 6.一个简单的时间获取服务器程序
  • 7.OSI模型

一个简单的时间获取客户程序

 #include
 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  ");
	if((sockfd=socket(AF_INET,SOCK_STREAM,0)) < O)
 		err_sys("socket error");
	bzero(&servaddr,sizeof(servaddr));
 	servaddr.sin_family=AF_INET;
	servaddr.sin_port=htons(13); / * daytime server */
	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);
 }

1.创建TCP套接字

socket创建一个网际(AF_INET)字节流(SOCK_STREAM)套接字

2.指定服务器的IP地址和端口

2.1htons()函数

由于不同的机器主机字节序不同,不同体系结构的机器之间无法通信,所以要转换成一种约定的字节序,也就是网络字节序即使是同一台机器上的两个进程(比如一个由C语言,另一个由Java编写)通信,也要考虑字节序的问题(JVM采用大端字节序)。

网络字节序与主机字节序之间的转换函数: htons()…ntohs)…htonl()、ntohl).htons和ntohs完成16位无符号数的相互转换,htonl和ntohl完成32位无符号数的相互转换。host to network short long

2.2新型网路地址转化函数inet_pton和inet_ntop

这两个函数是随IPv6出现的函数,对于IPv4地址和IPv6地址都适用,函数中p和n分别代表表达(presentation)和数值(numeric)。地址的表达格式通常是ASCII字符串,数值格式则是存放到套接字地址结构的二进制值。

#include 
int inet_pton(int family, const char *strptr, void *addrptr);     //将点分十进制的ip地址转化为用于网络传输的数值格式
        返回值:若成功则为1,若输入不是有效的表达式则为0,若出错则为-1
 
const char * inet_ntop(int family, const void *addrptr, char *strptr, size_t len);     //将数值格式转化为点分十进制的ip地址格式
        返回值:若成功则为指向结构的指针,若出错则为NULL

3.建立与服务器的连接

int connect(int sockfd, const struct sockaddr *servaddr, int *addrlen);
 返回:若成功则返回0,失败则返回-1

sockfd是有socket函数返回的套接字描述符,第二个、第三个参数分别是一个指向套接字地址结构的指针和该结构的大小。套接字地址结构必须含有服务器的IP地址和端口号。

4.读入并输出服务器的应答

我们使用read函数读取服务器的应答,并用标准的I/O函数fputs输出结果。

5.错误处理:包裹函数

当发生错误时,调用自己的err_quit或err_sys函数输出一个错误信息并终止程序的运行,所以定义包裹函数来缩短程序。约定包裹函数名是实际函数名的首字母大写形式。例如:
socket()包裹函数Socket()

    int Socket(int family, int type, int protocol)
    {
          int n = socket(family, type, protocol);
          if(n < 0)
          {
         	 perror("socket error!\n");
           	 exit(0);
          }
          return n;
    }

6.一个简单的时间获取服务器程序

#include    "unp.h"
#include    

int
main(int argc, char **argv)
{
    int             listenfd, connfd;
    struct sockaddr_in  *servaddr;
    char            buff[MAXLINE];
    time_t          ticks;

    listenfd = Soceket(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);

    Bind(listenfd, (SA *)&servaddr, sizeof(servaddr));  

    Listen(listenfd, LISTENO);
    for ( ; ; ) {
        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);
    }
}

1.把服务器的众所周知端口捆绑到套接字。我们制定IP地址为INADDR_ANY,这样要是服务器主机有多个网络接口,服务器进程就可以在任意网络接口上接受客户端连接。

2.将套接字转换成监听套接字。调用listen函数。

3.接受客户端连接,发送应答。TCP连接使用所谓的三路握手(three-way handshake)来建立连接。握手完毕时accept返回,其返回值是一个称为已连接描述符的新描述符。

4.终止连接close

7.OSI模型

学习unix网络编程第一章_第1张图片

你可能感兴趣的:(UNIX网络编程,网络,学习,unix)