Unix网络编程学习笔记之第1章 简介

一、一个简单的时间获取客户端

#include <sys/socket.h>
#define MAXCON 50
#define MAXLINE 1024
#define PORT 13
void err_sys(const char* s)
{
    fprintf(stderr, "%s\n",s);
    exit(1);
}
int main(int argc, char** argv)
{
    int sockfd;
    structsockaddr_in servaddr;
    char buff[MAXLINE+1];
    if(argc!=2)
        err_sys("inputerror");
    if((sockfd=sock(AF_INET,SOCK_STREAM, 0))<0)
        err_sys("socketerror");
    servaddr.sin_fimly=AF_INET;
    servaddr.sin_port=htons(PORT);
    if(inet_pton(AF_INET,argv[1], &servaddr.sin_addr)<=0)
        err_sys("ipaddress error");
    if(connect(sockfd,(struct sockaddr *)servaddr, sizeof(servaddr))<0)
        err_sys("connecterror");
    int nbyte;
    while((nbyte=read(sockfd,buff, MAXLINE))<0)
    {
        buff[nbyte]=0;
        if(fputs(buff,stdout)==EOF)
            err_sys("fputserror");
    }
    if(n<0)
        err_sys("readerror");
    exit(0);
}

1. read返回0,表示客户端正常关闭连接。

read返回负值,表示连接发生错误。

2. 此时我们把read写在while循环内,因为我们无法确定服务器端传过来的数据多大,如果一次读不完,就需要多次读取。

3. Unix终止进程运行,总是关闭该进程打开的所有描述符。

4. 一个Unix函数中有错误发生,全局变量errno就会被置为一个指明该错误类型的正值。这些正值对于的枚举名通常在<sys/errno.h>中定义。值0不表示任何错误。

注意:这里说的Unix函数说的是Unix自身库的函数,不是用户自定义的函数。

注意:线程函数在发送错误时,不设置全局变量errno,而是把errno的值作为函数返回值返回给调用者。

5. 注意这里的servaddr表明的是服务端的地址。

二、 一个简单的时间获取服务端

#include <sys/socket.h>
#define MAXLINE 1024
#define PORT 13
#define CONMAX 5
void err_sys(const char* s)
{
    fprintf(stderr, "%s\n",s);
    exit(1);
}
int main(int argc, char** argv)
{
    intlistenfd, connfd;
    structsockaddr_in servaddr;
    charbuff[MAXLINE+1];
    listenfd=socket(AF_INET, SOCK_STREAM, 0);

    bzero(&servaddr,sizeof(servaddr));
    servaddr.sin_family=AF_INET;
    servaddr.port=htona(PORT);
    servaddr.sin_addr.s_addr=htonl(INADDR_ANY);

    bind(listenfd,(structsockaddr*) &servaddr, sizeof(servaddr));

    listen(listenfd, CONMAX);

    while(true)
    {
        connfd=accept(listenfd, (struct sockaddr*) NULL, NULL);
        write(connfd, buff, strlen(buff));
        close(connfd);
    }
}
// socket bind listen connect accept 涉及socket的这些函数正常情况下都返回一个正值,在错误情况下都返回一直负值。
//这里就不做错误检查了。

1. 注意这里是单线程,单进程。一次只能处理一个客户。如果有两个客户几乎同时到达,则系统在最大数目(CONMAX)的限制下,把它们排入队列中。

时间: 2024-10-17 03:13:31

Unix网络编程学习笔记之第1章 简介的相关文章

Unix网络编程学习笔记之第2章 TCP和UDP

TCP 1. TCP面向连接的协议,是一个字节流协议,没有任何记录边界.发送的是数据分组. 2. TCP提供了可靠性:确认重传和重组 (1) TCP每发送一份数据都会要求对端进行确认.如果超时,就会重传.TCP会估计往返时间RTT,以确定等待多长时间重传. (2) 如果多次发送数据分组,TCP可以保证分组的按序达到.即会根据序列号进行重组. 3. TCP提供流量控制 TCP在任何时刻通知对端,它此时一次能够接受多少字节的数据,即通告窗口.该窗口指出接受缓冲区当前可用的空间. 4. 为何说TCP是

Unix网络编程学习笔记之第7章 套接字选项

一.获取/设置套接字选项的方法 一个套接字描述符相关联的套接字选项很多.获取/设置套接字选项的方法: 1.  getsockopt和setsockopt函数 2. fcntl函数 3. ioctl函数 二. getsockopt和setsockopt函数 int getsockopt(int sockfd, int level, int optname, void* optval, socklen_t* optlen); int setsockopt(int sockfd, int level,

Unix网络编程学习笔记之第6章 I/O复用:select和poll函数

一.I/O复用应用场合 1. 当客户处理多个描述符(既有标准输入,又有网络套接字)时,必须使用IO复用. 2. 一个客户同时处理多个套接字是可能的. 3. 如果一个服务器既要处理监听套接字,又要处理已连接套接字,一般就要使用I/O复用. 4. 如果一个服务器既要处理TCP,又要处理UDP,一般就要I/O复用. 5. 如果一个服务器要处理多个服务或协议,就要用到I/O复用. 其实IO复用就是一个进程/线程处理多个套接字描述符. 二. I/O模型 Unix提供了5种I/O模型: 1. 阻塞式I/O模

Unix网络编程学习笔记之第8章 基于UDP套接字编程

一. UDP C/S的典型函数调用 UDP没有像TCP那样的连接,客户端直接sendto向某服务器发送数据,服务器端一直recvfrom阻塞,以接收任何客户端发送的数据. 二. sendto和recvfrom函数 int sendto(int sockfd, const void* buff, size_t nbytes, int flag, const struct sockaddr* to, socklen_taddrlen); int recvfrom(int sockfd, void*

Unix网络编程学习笔记之第11章 名字与地址转换

一. 域名系统(DNS) 1. 简介 DNS主要用于主机名和IP地址之间的映射. 主机名可以是简单的名字ljm,也可以是全限定域名ljm.localdomainbaidu.com等. 2.资源记录 DNS中的条目称为资源记录(RR).我们感兴趣的RR类型只有几个: A             A记录把一个主机名映射为一个32位的IPv4地址. AAAA    4A记录把一个主机名映射为一个128位的IPv6地址. 例如: ljm               IN      A    127.0.

Unix网络编程学习笔记之第5章 TCP客户端/服务器程序示例

一. 一个简单TCP回射服务端程序 #include "unp.h" #define MAXLINE 1024 #define PORT 13 #define CONMAX 5 void err_sys(const char* s) { fprintf(stderr, "%s\n",s); exit(1); } void str_echo(int connfd) { int nbyte; char buff[MAXLINE+1]; again: while(nbyt

Unix网络编程学习笔记之第12章 IPv4与IPv6的互操作性

一. 简介 假设我们本章讨论的主机都是支持双栈的,即支持IPv4地址,也支持Ipv6地址. 我们本次讨论的点:客户端与服务器端使用的是不同类型的地址.因为相同类型的地址没什么可讲的. 二. IPv4客户端与IPv6服务器 即,客户端使用IPv4地址套接字来通信,服务器端使用IPv6地址套接字通信. 原理: 0. 首先IPv6服务器主机保证既有IPv4地址,又有IPv6地址. 1. IPv4客户端通过getaddrinfo函数,找到服务器端的IPv4地址,然后进行连接. 2. 来自客户端的IPv4

Unix网络编程学习笔记之第4章 基于TCP套接字编程

1. socket函数 int socket(int family, int type,int protocol) 成返回一个套接字描述符.错误返回-1 其中family指定协议族,一般IPv4为AF_INET, IPv6为AF_INET6. 其中type指定套接字类型,字节流:SOCK_STREAM.   数据报:SOCK_DGRAM. 一般情况下通过family和type的组合都可以唯一确定一个套接字类型.所以一般我们就把protocol设为0就可以了. 有时在某些特殊情况下,family和

UNIX网络编程学习笔记2 需要用到的一些字节操纵和格式转换函数

当然这些东西是炒鸡无聊的,但是真当自己开始撸代码时才发现熟悉这些枯燥的函数能够节约大量的时间.于是总结一下: 字节序:低序字节存储在起始地址,这称为小端(little-endian),高序字节存储在起始地址,这称为大端(big-endian) 例:存放0x0A0B0C0D LE: 0D 0C 0B 0A BE: 0A 0B 0C 0D 小端的存放方式更加接近于人类思维 网际协议使用大端字节序来传送多字节整数(为何要规定一个字节序来传输ip和port? 呸 这样子协议才能正确“看懂”(解释)这些地