精华内容
下载资源
问答
  • Unix网络编程

    2018-12-24 14:33:28
    该文档是Unix网络编程的pdf文档,讲解十分详细,欢迎大家下载学习
  • UNIX网络编程

    2019-10-04 10:06:37
    UNIX网络编程——socket的keep http://www.68idc.cn/help/opersys/unixbsd/20150731471448.html 转载于:https://www.cnblogs.com/ITniu/p/5932569.html

    UNIX网络编程——socket的keep
    http://www.68idc.cn/help/opersys/unixbsd/20150731471448.html

    转载于:https://www.cnblogs.com/ITniu/p/5932569.html

    展开全文
  • UNIX网络编程 UNIX网络编程的练习参考书籍: 《 Unix / Linux编程实践教程》 《 UNIX网络编程》 《 UNIX环境高级编程》
  • UNIX 网络编程

    2019-02-24 19:52:35
    1 socket网络编程步骤 1.1 服务器编程步骤 1.2 客户端编程步骤 1.3 函数以及结构解释 2 基于TCP的一对多网络编程 2.1 服务器编程步骤 2.2 客户端编程 2.3 函数解释 2.4 基于TCP的网络聊天室 3 基于UDP的一...

    目录

    1 socket网络编程步骤

    1.1 服务器编程步骤

    1.2 客户端编程步骤

    1.3 函数以及结构解释

    2 基于TCP的一对多网络编程

    2.1 服务器编程步骤

    2.2 客户端编程

    2.3 函数解释

    2.4 基于TCP的网络聊天室

    3 基于UDP的一对多编程

    3.1 服务器编程步骤

    3.2 客户端编程步骤

    3.3 UDP下的读写数据

    3.4 函数解释

    3.5 基于UDP的时间服务器代码


    本文要讲解Unix下的网络编程,即socket编程,也称为套接字编程。

    Unix系统在网络上功能十分强大,历史悠久,因此有一个非常固定的套路,代码比较僵化,没有改变的余地。Socket编程主要包括两个方面,一个是本地通信,即计算机内部的进程间的通信(IPC),这个本文不过多讲解,主要集中在后面的内容,网络通信。

    本文先介绍Unix网络编程的基本框架,以及具体的函数用法、结构体,然后分别介绍TCP网络编程和UDP网络编程。本文只介绍编程框架,而不会涉及具体的协议。

    1 socket网络编程步骤

    网络编程要考虑两个方面:服务器端和客户端,客户端通过网络与服务器端通信。

    1.1 服务器编程步骤

    1、调用函数socket(),用来创建socket描述符。

        int fd=socket(AF_INET,SOCK_DGRAM,0);
    
        if(fd==-1)
    
            perror("socket"),exit(-1);

     

    2、准备通讯地址(三个结构体),进行数据交互。

    struct sockaddr_in addr;
    
    addr.sin_family=AF_INET;
    
    addr.sin_port=htons(2222);//服务器的端口
    
    addr.sin_addr.s_addr=inet_addr("192.168.1.112");//服务器的ip地址

     

    3、绑定通讯地址和socket描述符,函数bind()

        int res=bind(fd,(struct sockaddr*)&addr,sizeof(addr));
    
        if(res==-1)
    
            perror("bind "),exit(-1);
    
        else
    
            printf("绑定成功\n");

     

    4、读写描述符,和读写文件描述符一样,函数read()/write()。

        char buf[100]={};
    
        res=read(fd,buf,sizeof(buf));

     

    5、使用函数close()关闭socket描述符。

    close(fd);

    1.2 客户端编程步骤

    1、调用函数socket(),用来创建socket描述符。

        int fd=socket(AF_INET,SOCK_DGRAM,0);
    
        if(fd==-1)
    
            perror("socket "),exit(-1);

     

    2、准备通讯地址(三个结构体),进行数据交互。

        struct sockaddr_in addr;
    
        addr.sin_family=AF_INET;
    
        addr.sin_port=htons(2222);//服务器
    
        addr.sin_addr.s_addr=inet_addr("192.168.1.112");

     

    3、绑定通讯地址和socket描述符,函数connect()

        int res=connect(fd,(struct sockaddr*)&addr,sizeof(addr));
    
        if(res==-1)
    
            perror("connect "),exit(-1);

     

    4、读写描述符,和读写文件描述符一样,函数read()/write()。

      write(fd,"hello",5);

    5、使用函数close()关闭socket描述符。

        close(fd);

    除了1.3的bind()换成connect()之外,其他的与服务器端一样,而且connect()和bind()用法完全一样。

    1.3 函数以及结构解释

    1、socket() 函数

    int socket( int domin , int type , int protocol);

    参数解释

    domin用于选择协议簇,可以选择一下的宏:

    AF_UNIX/AF_LOCAL/AF_FILE :本地通信

    AF_INET : 网络通信IPv4 (一般使用这个)

    AF_INET6 :网络通信IPv6

    type 用于选择通信的类型,主要包括:

    SOCK_STREAM :数据流,用于TCP。

    SOCK_DGRAM :数据报,用于UDP。

    protocol参数本来应该指定协议,但是由于协议已经被前两个参数确定了,所以直接将protocol给0即可,这是Unix网络编程的僵化的体现。

    如果函数执行成功,返回socket描述符,失败返回-1.

    这个函数用来生成一个socket描述符。

    2、结构体

    网络通信需要三个结构体来指定网络信息,分别是struct sockaddr、struct sockaddr_un、struct sockaddr_in。其中sockaddr主要用于做函数的参数,并不储存数据,即没啥实际的用处,socjaddr_un负责存储本地通信的地址数据,sockaddr_in负责存储网络通信的地址数据。

    #include <sys/un.h>
    
    struct sockaddr_un{
    
    int sun_family; //用于指定协议簇,和socket()要保持一致
    
    char sun_path[]; //存socket文件名,作为交互的媒介
    
    }
    
    #include<netinet/in.h>
    
    struct sockaddr_in{
    
    int sin_family; //用于指定协议簇,和socket()一致
    
    short sin_port; //端口号
    
    struct in_addr sin_addr; //存储IP地址的结构
    
    }

     

    注:sockaddr_in / sockaddr_un 在做参数时必须类型转换为sockaddr,读写数据时,一方读数据,另一方必须写数据。

     

    3、bind()

    int bind(int sockfd , struct sockaddr* addr , socklen_t size);

    参数解释

    sockfd是socket文件描述符,即socket()函数的返回值。

    addr是通信地址的指针,需要做类型转换

    size是通信地址的大小,即sizeof(struct)。

    这个函数用来绑定自己的IP地址和端口号

    4、connect()

    int connect(int sockfd , const struct sockaddr *addr , socklen_t addrlen);

    参数解释

    sockfd是socket文件描述符,即socket()函数的返回值。

    addr是通信地址的指针,需要做类型转换

    size是通信地址的大小,即sizeof(struct)。

    TCP客户通过connect函数与服务端进行通信。

    2 基于TCP的一对多网络编程

    所谓的一对多编程,即只有一个服务器,有很多个客户端,现在基本都是一对多编程。TCP是一个基于连接的协议,在网络交互中,服务器和客户端要保持连接,不能断开。如果出现数据错误,TCP会重新发送,保证数据的正确和完整,但是资源的消耗比较大。

    2.1 服务器编程步骤

    1、socket()得到一个socket描述符

    2、准备通信地址 struct sockaddr_in

    3、绑定bind(),连接端口

    4、监听函数listen(),这个函数用来控制同一时刻连接的人数。

    5、等待客户端的连接,函数accept(),返回一个新的socket描述符,这个新的socket描述符用于读写交互。

    6、读写函数read()/write()

    7、关闭socket()

    2.2 客户端编程

    1、调用函数socket(),用来创建socket描述符。

    2、准备通讯地址(三个结构体),进行数据交互。

    3、绑定通讯地址和socket描述符,函数connect()

    4、读写描述符,和读写文件描述符一样,函数read()/write()。

    5、使用函数close()关闭socket描述符。

    这里的步骤和上面的客户端编程的步骤是一样的

    2.3 函数解释

    1、listen()

    该函数主要用于设置当有多个用户请求时,放入等待队列,等待队列的最大长度就是listen设置的。

    int listen( int sockfd , int backlog);

    参数解释

    sockfd 是你要设置的socket描述符

    backlog是队列的最大长度

    2、accept()

    int accept(int fd , struct sockaddr *addr , socklen_t *len);

    参数解释

    fd就是socket描述符

    addr是一个结构体指针,用于传出客户端的通信地址

    len是一个传入传出参数,传入addr的真实长度,传出接收到的客户端的通信地址的真实长度。(一般是相同的)

    返回:成功返回新的socket描述符,失败返回-1.

    2.4 基于TCP的网络聊天室

    1、服务端代码

    #include<stdio.h>
    #include<stdlib.h>
    #include<sys/socket.h>
    #include<netinet/in.h>
    #include<arpa/inet.h>
    #include<unistd.h>
    #include<string.h>
    #include<pthread.h>
    
    int sockall[100]; //存放socket描述符的数组
    int sum;          //聊天室人数
    
    int socket_findsit(){
    	for(int i=0;i<100;i++)
    		if(!sockall[i])
    			return i;
    	return -1;
    }
    
    void* task_chat(void* p){
    	int index=(int)p;
    	int fd=sockall[index];
    	char buf[100]={};
    	char name[100]={};
    	char news[200]={};
    	int i=0;
    
    	sum++;
    	printf("聊天室人数:%d\n",sum);
    	/*读取用户的用户名*/
    	int res=read(fd,name,sizeof(name));
    	printf("用户%s进入聊天室\n",name);
    	/*进入聊天环节*/
    	while(1){
    		res=read(fd,buf,sizeof(buf));
    		if(res==0)
    			break;
    		if(!strcmp(buf,"bye")){
    			printf("用户%s退出聊天室\n",name);
    			break;
    		}
    		sprintf(news,"%.*s:%.*s",strlen(name),name,strlen(buf),buf);
    		
    		for(i=0;i<100;i++){
    			if(sockall[i])
    				write(sockall[i],news,strlen(news));
    		}
    		memset(buf,0,strlen(buf));
    		memset(news,0,strlen(news));
    	}
    	close(fd);
    	sockall[index]=0;
    	sum--;
    	printf("聊天室人数:%d\n",sum);
    	return NULL;
    }
    
    
    int main(){
    	pthread_t id;
    	int fd=socket(AF_INET,SOCK_STREAM,0);//TCP协议
    	if(fd==-1)
    		perror("socket "),exit(-1);
    
    	struct sockaddr_in addr;
    	addr.sin_family=AF_INET; //协议簇
    	addr.sin_port=htons(2222);
    	addr.sin_addr.s_addr=inet_addr("192.168.1.112");
    	/*防止复用*/
    	int reuse=1;
    	setsockopt(fd,SOL_SOCKET,SO_REUSEADDR,&reuse,sizeof(reuse));
    
    	int res=bind(fd,(struct sockaddr*)&addr,sizeof(addr));
    	if(res==-1)
    		perror("bind "),exit(-1);
    	printf("成功绑定端口\n");
    
    	listen(fd,100);//设置等待队列的长度
    	int index;
    	while(1){
    		struct sockaddr_in from;
    		socklen_t len=sizeof(from);
    		int sockfd=accept(fd,(struct sockaddr*)&from,&len);
    		index=socket_findsit();
    		if(index!=-1){
    			sockall[index]=sockfd;
    			pthread_create(&id,0,task_chat,(void*)(index));
    		}
    		else{
    			printf("聊天室人数已满\n");
    		}
    	}
    
    }
    

     

     

    2、客户端代码

    #include<stdio.h>
    #include<stdlib.h>
    #include<unistd.h>
    #include<sys/socket.h>
    #include<netinet/in.h>
    #include<arpa/inet.h>
    #include<string.h>
    #include<pthread.h>
    void* task_read(void*p){
    	int fd=(int)p;
    	char buf[200]={};
    	while(1){
    		read(fd,buf,sizeof(buf));
    		printf("%s\n",buf);
    		memset(buf,0,strlen(buf));
    	}
    }
    
    
    int main(){
    	pthread_t id;
    	int fd=socket(AF_INET,SOCK_STREAM,0);
    	if(fd==-1)
    		perror("socket "),exit(-1);
    
    	struct sockaddr_in addr;
    	addr.sin_family=AF_INET;
    	addr.sin_port=htons(2222);
    	addr.sin_addr.s_addr=inet_addr("114.116.5.220");
    
    	int res=connect(fd,(struct sockaddr*)&addr,sizeof(addr));
    	if(res==-1)
    		perror("connect "),exit(-1);
    	printf("成功连接服务器!\n");
    
    	char buf1[100]={};
    	char buf2[100]={};
    
    	printf("请输入您的用户名:\n");
    	scanf("%s",buf1);
    	write(fd,buf1,strlen(buf1));
    	memset(buf1,0,sizeof(buf1));
    	printf("欢迎来到聊天室!\n");
    	
    	pthread_create(&id,0,task_read,(void*)fd);
    	while(1){
    		scanf("%s",buf1);
    		write(fd,buf1,strlen(buf1));
    		if(!strcmp(buf1,"bye"))
    			break;
    		memset(buf1,0,strlen(buf1));
    	}
    	close(fd);
    }
    

     

     

    3 基于UDP的一对多编程

    UDP协议,用户数据报协议,无需连接,消耗资源少,但是有可能出错。

    3.1 服务器编程步骤

    1、socket(),得到socket描述符

    2、准备通信地址,strutc sockaddr_in

    3、绑定bind()

    4、读写

    5、关闭描述符

     

    3.2 客户端编程步骤

    1、socket(),得到socket描述符

    2、准备通信地址,strutc sockaddr_in

    3、读写

    4、关闭描述符

    客户端不需要绑定或者连接。

     

    3.3 UDP下的读写数据

    UDP协议下,使用的读写函数与TCP不同,在不连接的前提下,读数据使用read()或者recvfrom(),read()只能读数据,不能读对方发送方的通信地址,而recvfrom两者皆可。写数据使用sendto(),不能使用write()。

     

    3.4 函数解释

    1、recvfrom()

    size_t recvfrom( int fd , void *buf , size_t len , int flags , struct sockaddr *src_addr , socklen_t *addrlen);

    参数解释

    fd 文件描述符,在这里就是socket描述符,buf是要将文件读取进的对象,len是读取的长度,flags一般给0即可,src_addr是一个传出参数,用于接收发送方的通信地址,addrlen是一个传入传出参数,传入addr的真实长度,传出接收到的客户端的通信地址的真实长度。

    2、sendto()

    int sendto(int fd , void *addr , size_t len , int flag , struct sockaddr *addr , socklen_t addlen);

    参数解释

    fd是文件描述符,addr是要写入的内容指针,len是要写入的长度,addr 传入数据接收方的通信地址,addrlen就是通信地址的长度。

    返回:成功返回发送的字节数,失败返回-1。

     

    3.5 基于UDP的时间服务器代码

    1、服务器代码

    #include<stdio.h>
    #include<stdlib.h>
    #include<unistd.h>
    #include<sys/socket.h>
    #include<netinet/in.h>
    #include<arpa/inet.h>
    #include<time.h>
    #include<string.h>
    
    int main(){
    	int fd=socket(AF_INET,SOCK_DGRAM,0);
    	if(fd==-1)
    		perror("socket "),exit(-1);
    	struct sockaddr_in addr;
    	addr.sin_family=AF_INET;
    	addr.sin_port=htons(2222);
    	addr.sin_addr.s_addr=inet_addr("192.168.1.112");
    
    	int res=bind(fd,(struct sockaddr*)&addr,sizeof(addr));
    	if(res==-1)
    		perror("bind "),exit(-1);
    	printf("bind ok\n");
    
    	char buf[100]={};
    	while(1){
    		struct sockaddr_in from;
    		socklen_t len=sizeof(from);
    
    		res=recvfrom(fd,buf,sizeof(buf),0,(struct sockaddr*)&from,&len);
    		
    		pid_t pid=fork();
    		if(!pid){
    			time_t time1=time(NULL);
    			struct tm* tm1=localtime(&time1);
    			printf("读到了%d字节,内容:%s\n",res,buf);
    			memset(buf,0,sizeof(buf));
    			sprintf(buf,"%d/%d/%d  %d:%d:%d",tm1->tm_year+1900,tm1->tm_mon+1,tm1->tm_mday,tm1->tm_hour,tm1->tm_min,tm1->tm_sec);
    			sendto(fd,buf,sizeof(buf),0,(struct sockaddr*)&from,len);
    			exit(0);
    		}
    	}
    }
    
    

     

     

    2、客户端代码

    #include<stdio.h>
    #include<stdlib.h>
    #include<unistd.h>
    #include<sys/socket.h>
    #include<netinet/in.h>
    #include<arpa/inet.h>
    
    int main(){
    	int fd=socket(AF_INET,SOCK_DGRAM,0);
    	if(fd==-1)
    		perror("socket "),exit(-1);
    	struct sockaddr_in addr;
    	addr.sin_family=AF_INET;
    	addr.sin_port=htons(2222);
    	addr.sin_addr.s_addr=inet_addr("192.168.1.112");
    
    	sendto(fd,"hello",5,0,(struct sockaddr*)&addr,sizeof(addr));
    	char buf[100]={};
    	int res=read(fd,buf,sizeof(buf));
    	printf("日期:%s\n",buf);
    	close(fd);
    	return 0;
    }
    

     

     

    展开全文
  • Unix 网络编程

    2017-02-09 23:34:03
    以前用Java语言和Erlang做的网络编程的例子和这本书比起来,简直是弱爆了。以前的我,是多么的天真啊。当初,我没有在Java和Erlang的网络方面下大功夫,因为那时我觉得如果不能在C的层面学明白这
    2013-03-18

                                                   

          

       看了这本书,才真正了解到什么才是网络编程。以前用Java语言和Erlang做的网络编程的例子和这本书比起来,简直是弱爆了。以前的我,是多么的天真啊。当初,我没有在Java和Erlang的网络方面下大功夫,因为那时我觉得如果不能在C的层面学明白这些东西,用高级语言也是惘然的,定是收益没有直接使用C编写网络代码的收益多。至今我仍这样觉得。,过在C语言层面进行网络方面的学习应该是最节省时间的方式。一通百通,之后,再在其他语言上使用的话就能省更多的时间了。

       对比了一下发现,XTI;X/Open部分被完全删掉了,新增了有关SCTP的章节。这个SCTP有那么重要吗?新增的两位作者也真敢往上加东西。半年后再评论吧,看看是否这个协议真的很重要。关于TCP和UDP的讲解实在是太精彩了。

      这个第三版真是奇葩哈,连翻译者的名字都没有,一大群人都这么粗心。

     

    展开全文
  • unix 网络编程

    2017-05-31 11:43:29
  • unix网络编程.pdf

    2018-04-17 11:59:29
    unix网络编程.pdf unix网络编程.pdf unix网络编程.pdf
  • unix网络编程

    2016-08-15 10:07:58
    为了执行网络I/O,一个进程必须做的第一件事就是调用socket函数,指定期望的通信协议类型,客户端和服务器端都需要socket()函数(该套接字从socket()开始为CLOSED状态) #include int socket(int
  • 这一篇介绍一下Unix网络编程的5种I/O模型,在介绍这5中I/O模型之前先介绍一下Unix网络编程中同步/异步和阻塞/非阻塞以及用户空间和内核空间的概念用户空间和内核空间在Linux/Unix中,对于一次读取IO的操作,数据并...
  • UNIX网络编程(第二版中英文,第三版中英文<卷1>),UNIX环境高级编程(第二版中文版,第三版英文版),全为PDF格式,有人单个资源就要3分,有点坑,我免费给大家下载一下,希望对你有用。另外,UNIX环境高级编程...
  • unix环境高级编程&&unix网络编程两本书,学习unix/linux程序设计必备!
  • unix网络编程源码

    千次下载 热门讨论 2014-07-30 10:31:09
    unix网络编程源码,包括unpipc.h头文件
  • UNIX网络编程.zip

    2019-05-15 14:05:28
    经典网络编程书籍, mobi格式 ,适合Kindle阅读 。UNIX网络编程 第一卷.mobi
  • UNIX网络编程 卷1 源代码UNIX网络编程 卷1 源代码UNIX网络编程 卷1 源代码
  • UNIX网络编程 技术API接口 UNP 技术接口
  • UNIX编程丛书:介绍参照百度百科 Unix编程艺术 Unix环境高级编程(第二版) Unix网络编程(第二版)
  • UNIX网络编程 卷2

    2018-04-23 14:22:01
    UNIX网络编程 卷2:进程间通信第2版 文字版

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 9,112
精华内容 3,644
关键字:

unix网络编程