linux 网络编程

一. 网络编程概述

1. 概述

网络通信手段的一种,我们在之前学了进程间通信,包括管道、消息队列、共享内存、信号和信号量,这些通信方式有一个共同的特点,就是他们都是在依赖Linux内核在单机上进行进程的通信,而面对多机之间的通信,这些手段就远远不够了。所以我们引入网络,利用网络来实现多机之间的通信。

多机通信有好多例子,比如Linux服务器和Adroid、 IOS、C51、x86的Linux之间的通信。 既然谈到网络编程,就一定需要地址,包括IP地址和端口号。IP地址用来标识一台设备,端口号用来标识一台设备上的进程。除了这个,还需要协议来作为支撑,包括TCP、UDP和HTTP协议等,协议作为一种规则,约定了通信双方的数据格式,就好比两个人必须都用中文才能听懂对方说话。

我们在这里主要用到的是Socket网络编程,也叫套接字网络编程,主要用到TCP和UDP协议。

2. TCP/UDP

1、TCP面向连接(如打电话要先拨号建立连接) ;UDP是无连接的,即发送数据之前不需要建立连接
2、TCP提供可靠的服务。也就是说,通过TCP连接传送的数据,无差错,不丢失,不重复,且按序到达;UDP尽最大努力交付,即不保证可靠交付
3、TCP面向字节流,实际上是TCP把数据看成一连串无结构的字节流;UDP是面向报文的UDP没有拥塞控制,因此网络出现拥塞不会使源主机的发送速率降低(对实时应用很有用,如IP电话,实时视频会议等)
4、每一条TCP连接只能是点到点的;UDP支持一对一,一对多, 多对一和多对多的交互通信
5、TCP首部开销20字节;UDP的首部开销小,只有8个字节
6、TCP的逻辑通信信道是全双工的可靠信道,UDP则是不可靠信道

3. 端口号作用

一台拥有IP地址的主机可以提供许多服务,比如Web服务、FTP服务、SMTP服务等。

这些服务完全可以通过1个IP地址来实现。那么,主机是怎样区分不同的网络服务呢?显然不能只靠IP地址,因为IP 地址与网络服务的关系是一对多的关系。

实际上是通过“IP地址+端口号”来区 分不同的服务的。端口提供了一种访问通道,服务器一般都是通过知名端口号来识别的。例如,对于每个TCP/IP实现来说,FTP服务器的TCP端口号都是21,每个Telnet服务器的TCP端口号都是23,每个TFTP(简单文件传送协议)服务器的UDP端口号都是69。3000以下的端口号一般是操作系统所使用的,用户一般使用5000到9000的端口号。

二. 字节序

字节序是指多字节数据在计算机内存中存储或者网络传输时各字节的存储顺序。
字节序分为小端字节序和大端字节序:

  • Little endian:将低序字节存储在起始地址
  • Big endian:将高序字节存储在起始地址

在这里插入图片描述
TCP/IP协议规定,网络数据流应采用大端字节序

为使网络程序具有可移植性,使同样的C代码在大端和小端计算机上编译后都能正常运行,可以调用以下库函数做网络字节序和主机字节序的转换:

#include <arpa/inet.h>
 
uint32_t htonl(uint32_t hostlong);
uint16_t htons(uint16_t hostshort);
uint32_t ntohl(uint32_t netlong);
uint16_t ntohs(uint16_t netshort);
//h表示host,n表示network,l表示32位长整数,s表示16位短整数。
//如果主机是小端字节序,这些函数将参数做相应的大小端转换然后返回,如果主机是大端字节序,这些函数不做转换,将参数原封不动地返回。

注意,网络字节序指的是大端字节序。

三. socket编程步骤

1. 创建套接字—socket()
2. 为套接字添加信息(IP地址和端口号)—bind()
3. 监听网络连接—listen()
4. 监听到有客户端接入,接受一个连接—accept()
5. 数据交互
6. 关闭套接字,断开连接

四. linux提供的API简析

1. 连接协议

int socket(int domain, int type, int protocol);
(1)domain:通常是AF_INET,指IPV4因特网域
(2)type:指定socket类型,SOCK_STREAM它使用TCP协议,SOCK_DGRAM使用UDP协议
(3)protocol:0默认选择type对应的协议
创建失败返回-1.

在这里插入图片描述

2. 连接地址

int bind(int sockfd, const struct sockaddr *maddr,socklen_t addrlen);
(1)sockfd:网络标识符
(2)struct sockaddr_in{
     sa_family_t sin_family;  //指定AF_***,表示使用什么协议族的ip格式
     in_port_in      sin_port;   //设置端口号
     struct in_addr  sin_addr;   //设置ip
     unsigned char sin_zero[8];
};
(3)结构体大小

在这里插入图片描述
其中:struct in_addr sin_addr; //设置ip 中struct in_addr结构体:

3. 地址转换API

把字符串形式的“192.168.1.123”转为网络能识别的格式:

int inet_aton(const char* straddr,struct in_addr *addrp);

网络格式的ip地址转为字符串形式:

char* inet_ntoa(struct in_addr inaddr); 

4. 监听

int listen(int sockfd,int backlog)

(1)sockfd:网络连接号
(2)backlog:指定请求队列中同时最大请求数 

在这里插入图片描述

5. 连接

int accept(int sockfd,struct sockaddr *addr,socklen_t addrlen)

(1)网络连接号
(2)客户端地址,NULL
(3)客户端地址长度,NULL(指针) 返回值是新建立的通道。

6. 数据收发

在这里插入图片描述

7. 客户端的connect函数

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

(1)目的服务器端口号
(2)服务器的IP地址和端口号的结构体
(3)地址长度

五. socket服务端编程

#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>          /* See NOTES */
#include <sys/socket.h>
#include <arpa/inet.h>
#include <netinet/in.h>

int main()
{
        int s_fd;

        //1.socket
        //int socket(int domain, int type, int protocol);
        /*
        int socket(int domain, int type, int protocol);
		(1)domain:通常是AF_INET,指IPV4因特网域
		(2)type:指定socket类型,SOCK_STREAM它使用TCP协议,SOCK_DGRAM使用UDP协议
		(3)protocol:0默认选择type对应的协议
		创建失败返回-1.
		*/
        s_fd = socket(AF_INET,SOCK_STREAM,0);
        if(s_fd == -1){
                perror("socket");
                exit(-1);
        }
		/*
		int bind(int sockfd, const struct sockaddr *maddr,socklen_t addrlen);
		(1)sockfd:网络标识符
		(2)struct sockaddr_in{
		     sa_family_t sin_family;  //指定AF_***,表示使用什么协议族的ip格式
		     in_port_in      sin_port;   //设置端口号
		     struct in_addr  sin_addr;   //设置ip
		     unsigned char sin_zero[8];
		};
		(3)结构体大小	
		*/
        struct sockaddr_in s_addr;
        s_addr.sin_family = AF_INET;
        s_addr.sin_port = htons(8989);
        //把字符串形式的“192.168.1.123”转为网络能识别的格式
        //int inet_aton(const char* straddr,struct in_addr *addrp);
        inet_aton("192.168.239.135",&s_addr.sin_addr);//ben ji

        //2.bind
        //int bind(int sockfd, const struct sockaddr *addr,socklen_t addrlen);
        bind(s_fd,(struct sockaddr *)&s_addr,sizeof(struct sockaddr_in));

        //3.listen
        /*
		int listen(int sockfd,int backlog)
		(1)sockfd:网络连接号
		(2)backlog:指定请求队列中同时最大请求数
		*/
        //int listen(int sockfd, int backlog);  
        listen(s_fd,10);

        //4.accept
        /*
        int accept(int sockfd,struct sockaddr *addr,socklen_t addrlen)
		(1)网络连接号
		(2)客户端地址,NULL
		(3)客户端地址长度,NULL(指针) 返回值是新建立的通道。
		*/
        //int accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen);
        int c_fd = accept(s_fd,NULL,NULL);

        //5.read

        //6.write
        printf("connect!\n");
        while(1);
        return 0;
}

其中: inet_aton("192.168.239.135",&s_addr.sin_addr);中的192.168.239.135–另开端口使用指令查询:ifconfig
在这里插入图片描述
使用window的命令行窗口telnet 192.168.239.135 8989
在这里插入图片描述
已经成功连接!!!

//server.c
#include <stdio.h>
#include <sys/types.h>          /* See NOTES */
#include <sys/socket.h>
//#include <linux/in.h>
#include <arpa/inet.h>
#include <netinet/in.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>

//int socket(int domain, int type, int protocol);
//int bind(int sockfd, const struct sockaddr *addr,socklen_t addrlen);
//int accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen);

int main()
{
        int s_fd;
        int n_read;
        char readBuf[128];

        char *msg = "I get your message";
        struct sockaddr_in s_addr;
        struct sockaddr_in c_addr;

        memset(&s_addr,0,sizeof(struct sockaddr_in));
        memset(&c_addr,0,sizeof(struct sockaddr_in));

        //1.socket
        //1.创建套接字---socket()
        /*
        int socket(int domain, int type, int protocol);
		(1)domain:通常是AF_INET,指IPV4因特网域
		(2)type:指定socket类型,SOCK_STREAM它使用TCP协议,SOCK_DGRAM使用UDP协议
		(3)protocol:0默认选择type对应的协议
		创建失败返回-1.
		*/
        s_fd = socket(AF_INET, SOCK_STREAM,0);
        if(s_fd == -1){
                perror("socket");
                exit(-1);
        }
        s_addr.sin_family = AF_INET;//
        s_addr.sin_port = htons(8988);//转换大端字节序  //8988端口号
        inet_aton("192.168.3.250",&s_addr.sin_addr);//字符串格式转换为网络格式
        //2.bind
        //2.为套接字添加信息(IP地址和端口号)---bind()
        /*
		int bind(int sockfd, const struct sockaddr *maddr,socklen_t addrlen);
		(1)sockfd:网络标识符
		(2)struct sockaddr_in{
		     sa_family_t sin_family;  //指定AF_***,表示使用什么协议族的ip格式
		     in_port_in      sin_port;   //设置端口号
		     struct in_addr  sin_addr;   //设置ip
		     unsigned char sin_zero[8];
		};
		(3)结构体大小	
		*/
        bind(s_fd,(struct sockaddr *)&s_addr,sizeof(struct sockaddr_in));
        //3. listen
        //3.监听网络连接---listen()
        /*
		int listen(int sockfd,int backlog)
		(1)sockfd:网络连接号
		(2)backlog:指定请求队列中同时最大请求数
		*/
        listen(s_fd,10);//监听
        //4.accept
        //4.监听到有客户端接入,接受一个连接---accept()
         /*
        int accept(int sockfd,struct sockaddr *addr,socklen_t addrlen)
		(1)网络连接号
		(2)客户端地址,NULL
		(3)客户端地址长度,NULL(指针) 返回值是新建立的通道。
		*/
        int clen = sizeof(struct sockaddr_in);
        int c_fd = accept(s_fd,(struct sockaddr *)&c_addr,&clen);//
        if(c_fd == -1){
                perror("accept");
        }
        printf("get connect :%s\n",inet_ntoa(c_addr.sin_addr));//网络格式转换为字符串格式
        //5.read
        //5.数据交互
        n_read = read(c_fd,readBuf,128);
        if(n_read == -1 ){
                perror("read");
        }else{
                printf("get message:%d,%s\n",n_read,readBuf);
        }
        
        //6.write
        //数据交互
        write(c_fd,msg,strlen(msg));

        return 0;
}

运行结果:
在这里插入图片描述

六. socket客户端代码实现

//client.c
#include <stdio.h>
#include <sys/types.h>          /* See NOTES */
#include <sys/socket.h>
//#include <linux/in.h>
#include <arpa/inet.h>
#include <netinet/in.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>

int main()
{
        int c_fd;
        int n_read;
        char readBuf[128];

        char *msg = "message from client";
        struct sockaddr_in c_addr;

        memset(&c_addr,0,sizeof(struct sockaddr_in));

        //1.socket
         //1.创建套接字---socket()
        /*
        int socket(int domain, int type, int protocol);
		(1)domain:通常是AF_INET,指IPV4因特网域
		(2)type:指定socket类型,SOCK_STREAM它使用TCP协议,SOCK_DGRAM使用UDP协议
		(3)protocol:0默认选择type对应的协议
		创建失败返回-1.
		*/
        c_fd = socket(AF_INET, SOCK_STREAM,0);
        if(c_fd == -1){
                perror("socket");
                exit(-1);
        }

        c_addr.sin_family = AF_INET;//
        c_addr.sin_port = htons(8988);//zhuanhua daduanzijiexu  //duankouhao
        inet_aton("192.168.3.250",&c_addr.sin_addr);
        //2.connect
        /*
        connect(int sockfd,const struct sockaddr *addr,socklen_t addrlen)
		(1)目的服务器端口号
		(2)服务器的IP地址和端口号的结构体
		(3)地址长度
		*/
        if(connect(c_fd,(struct sockaddr *)&c_addr,sizeof(struct sockaddr)) == -1){
                perror("connect");
                exit(-1);
        }

        //3.send
        write(c_fd,msg,strlen(msg));

        //4.read
        n_read = read(c_fd,readBuf,128);
        if(n_read == -1 ){
                perror("read");
        }else{
                printf("get message from :%d,%s\n",n_read,readBuf);
        }

        return 0;
}
//与server.c相互配合

在这里插入图片描述

七. 实现双方聊天

首先实现服务器不退出操作

############################## serve.c ##################################
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>          /* See NOTES */
#include <sys/socket.h>
//#include <linux/in.h>
#include <arpa/inet.h>
#include <netinet/in.h>
#include <string.h>
#include <unistd.h>

int main(int argc,char **argv)
{
        int s_fd;
        int c_fd;
        int n_read;
        char readBuf[128];

        char *msg = "I get your message!";

        struct sockaddr_in s_addr;
        struct sockaddr_in c_addr;

        memset(&s_addr,0,sizeof(struct sockaddr_in));
        memset(&c_addr,0,sizeof(struct sockaddr_in));

        //1.socket
        //int socket(int domain, int type, int protocol);
        s_fd = socket(AF_INET,SOCK_STREAM,0);
        if(s_fd == -1){
                perror("socket");
                exit(-1);
        }

        s_addr.sin_family = AF_INET;
        s_addr.sin_port = htons(atoi(argv[2]));
        //int inet_aton(const char* straddr,struct in_addr *addrp);
        inet_aton(argv[1],&s_addr.sin_addr);//ben ji
        //2.bind
        //int bind(int sockfd, const struct sockaddr *addr,socklen_t addrlen);
        bind(s_fd,(struct sockaddr *)&s_addr,sizeof(struct sockaddr_in));

        //3.listen
        //int listen(int sockfd, int backlog);  
        listen(s_fd,10);

        //4.accept
        int clen = sizeof(struct sockaddr_in);
        while(1){
                //int accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen);
                c_fd = accept(s_fd,(struct sockaddr *)&c_addr,&clen);
                if(c_fd == -1){
                        perror("accept");
                }

                //char* inet_ntoa(struct in_addr inaddr); 
                printf("get connect:%s\n",inet_ntoa(c_addr.sin_addr));

                if(fork() == 0){

                        //5.read
                        //ssize_t read(int fd, void *buf, size_t count);
                        n_read = read(c_fd,readBuf,128);
                        if(n_read == -1){
                                perror("read");
                        }else{
                                printf("get message:%d,%s\n",n_read,readBuf);
                        }
                        //6.write
                        //ssize_t write(int fd, const void *buf, size_t count);
                        write(c_fd,msg,strlen(msg));
                        break;
                }
        }
        return 0;
}

################################### client.c ####################################
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>          /* See NOTES */
#include <sys/socket.h>
//#include <linux/in.h>
#include <arpa/inet.h>
#include <netinet/in.h>
#include <string.h>
#include <unistd.h>

int main(int argc,char **argv)
{
        int c_fd;
        int n_read;
        char readBuf[128];

        char *msg = "msg from client!";

        struct sockaddr_in c_addr;

        memset(&c_addr,0,sizeof(struct sockaddr_in));

        //1.socket
        //int socket(int domain, int type, int protocol);
        c_fd = socket(AF_INET,SOCK_STREAM,0);
        if(c_fd == -1){
                perror("socket");
                exit(-1);
        }

        c_addr.sin_family = AF_INET;
        c_addr.sin_port = htons(atoi(argv[2]));
        //int inet_aton(const char* straddr,struct in_addr *addrp);
        inet_aton(argv[1],&c_addr.sin_addr);//ben ji

        //2.connect
        //int connect(int sockfd, const struct sockaddr *addr,socklen_t addrlen)
        if(connect(c_fd,(struct sockaddr *)&c_addr,sizeof(struct sockaddr_in)) == -1){
                perror("connect");
                exit(-1);
        }

        //3.send
        //ssize_t write(int fd, const void *buf, size_t count);
        write(c_fd,msg,strlen(msg));

        //4.read
        //ssize_t read(int fd, void *buf, size_t count);
        n_read = read(c_fd,readBuf,128);
        if(n_read == -1){
                perror("read");
        }else{
                printf("get message from server:%d,%s\n",n_read,readBuf);
        }

        printf("connect!\n");
        return 0;
}

在这里插入图片描述
可见,服务端一直不退出,一直在接受消息!!!

//server.c
#include <stdio.h>
#include <sys/types.h>          /* See NOTES */
#include <sys/socket.h>
//#include <linux/in.h>
#include <arpa/inet.h>
#include <netinet/in.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>

//int socket(int domain, int type, int protocol);
//int bind(int sockfd, const struct sockaddr *addr,socklen_t addrlen);
//int accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen);

int main(int argc,char **argv)
{
        int s_fd;
        int c_fd;
        int n_read;
        char readBuf[128];

//      char *msg = "I get your message";
        char msg[128] = {0};
        struct sockaddr_in s_addr;
        struct sockaddr_in c_addr;

        if(argc != 3){
                printf("param is not good\n");
                exit(-1);
        }

        memset(&s_addr,0,sizeof(struct sockaddr_in));
        memset(&c_addr,0,sizeof(struct sockaddr_in));
        //1.socket
        s_fd = socket(AF_INET, SOCK_STREAM,0);
        if(s_fd == -1){
                perror("socket");
                exit(-1);
        }

        s_addr.sin_family = AF_INET;//
        s_addr.sin_port = htons(atoi(argv[2]));//zhuanhua daduanzijiexu  //duankouhao
        inet_aton(argv[1],&s_addr.sin_addr);

        //2.bind
        bind(s_fd,(struct sockaddr *)&s_addr,sizeof(struct sockaddr_in));

        //3. listen
        listen(s_fd,10);//jianting 10ge 
 //4.accept
        int clen = sizeof(struct sockaddr_in);
        while(1){

                c_fd = accept(s_fd,(struct sockaddr *)&c_addr,&clen);//
                if(c_fd == -1){
                        perror("accept");
                }

                printf("get connect :%s\n",inet_ntoa(c_addr.sin_addr));//wangluo zhaunhua  zifuchuan

                if(fork() == 0){//zijincheng

                        if(fork() == 0){
                                while(1){
                                        memset(msg,0,sizeof(msg));
                                        printf("input: ");
                                        gets(msg);
                                        //6.write
                                        write(c_fd,msg,strlen(msg));
                                        }
                                }
                        //5.read
                        while(1){
                                memset(readBuf,0,sizeof(readBuf));
                                n_read = read(c_fd,readBuf,128);
                                if(n_read == -1 ){
                                        perror("read");
                                }else{
                                        printf("get message:%d,%s\n",n_read,readBuf);
                                }
                        }
                        break;
                }
        }
        return 0;
}

//client.c
#include <stdio.h>
#include <sys/types.h>          /* See NOTES */
#include <sys/socket.h>
//#include <linux/in.h>
#include <arpa/inet.h>
#include <netinet/in.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>

//int socket(int domain, int type, int protocol);
//int bind(int sockfd, const struct sockaddr *addr,socklen_t addrlen);
//int accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen);

int main(int argc,char **argv)
{
        int c_fd;
        int n_read;
        char readBuf[128];

        //      char *msg = "message from client";
        char msg[128] = {0};

        struct sockaddr_in c_addr;
        if(argc != 3){
                printf("param is not good\n");
                exit(-1);
        }
        memset(&c_addr,0,sizeof(struct sockaddr_in));

        //1.socket
        c_fd = socket(AF_INET, SOCK_STREAM,0);
        if(c_fd == -1){
                perror("socket");
                exit(-1);
        }
 		c_addr.sin_family = AF_INET;//
        c_addr.sin_port = htons(atoi(argv[2]));//zhuanhua daduanzijiexu  //duankouhao
        inet_aton(argv[1],&c_addr.sin_addr);

        //2.connect
        if(connect(c_fd,(struct sockaddr *)&c_addr,sizeof(struct sockaddr)) == -1){
                perror("connect");
                exit(-1);
        }
		while(1){

                if(fork() == 0 ){
                        while(1){
                                memset(msg,0,sizeof(msg));
                                printf("input: ");
                                gets(msg);
                                //3.send
                                write(c_fd,msg,strlen(msg));
                        }
                }
                while(1){
                        memset(readBuf,0,sizeof(readBuf));
                        //4.read
                        n_read = read(c_fd,readBuf,128);
                        if(n_read == -1 ){
                                perror("read");
                        }else{
                                printf("get message from :%d,%s\n",n_read,readBuf);
                        }
                }
        }


        return 0;
}

在这里插入图片描述
双方开始沟通交流!!!

八. 多方信息收发

实现了服务端和客户端双方的聊天,但是我们遇到一个问题,就是当我们多开一个客户端的时候,客户端可以给服务端发消息,但是服务端给客户端发消息的时候,就会产生不确定的情况。就是当有多个客户端访问服务端的时候,服务端不知道把消息发送给谁,其无法解决精准的一对一的通信问题,经过一番研究发现,其实不是因为服务端无法对接客户端进程的问题,而是因为服务端输入发送内容时的光标无法解析发给谁的问题,下面对服务端代码做了一些改进,验证了能够实现服务端和客户端能够一对一精准通信的问题。

//server.c
#include <stdio.h>
#include <sys/types.h>          /* See NOTES */
#include <sys/socket.h>
//#include <linux/in.h>
#include <arpa/inet.h>
#include <netinet/in.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>

//int socket(int domain, int type, int protocol);
//int bind(int sockfd, const struct sockaddr *addr,socklen_t addrlen);
//int accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen);

int main(int argc,char **argv)
{
        int s_fd;
        int c_fd;
        int n_read;
        char readBuf[128];
		int mark = 0;
//      char *msg = "I get your message";
        char msg[128] = {0};
        struct sockaddr_in s_addr;
        struct sockaddr_in c_addr;

        if(argc != 3){
                printf("param is not good\n");
                exit(-1);
        }

        memset(&s_addr,0,sizeof(struct sockaddr_in));
        memset(&c_addr,0,sizeof(struct sockaddr_in));
        //1.socket
        s_fd = socket(AF_INET, SOCK_STREAM,0);
        if(s_fd == -1){
                perror("socket");
                exit(-1);
        }

        s_addr.sin_family = AF_INET;//
        s_addr.sin_port = htons(atoi(argv[2]));//zhuanhua daduanzijiexu  //duankouhao
        inet_aton(argv[1],&s_addr.sin_addr);

        //2.bind
        bind(s_fd,(struct sockaddr *)&s_addr,sizeof(struct sockaddr_in));

        //3. listen
        listen(s_fd,10);//jianting 10ge 
 //4.accept
        int clen = sizeof(struct sockaddr_in);
        while(1){

                c_fd = accept(s_fd,(struct sockaddr *)&c_addr,&clen);//
                if(c_fd == -1){
                        perror("accept");
                }
				mark ++;
                printf("get connect :%s\n",inet_ntoa(c_addr.sin_addr));//wangluo zhaunhua  zifuchuan

                if(fork() == 0){//zijincheng

                        if(fork() == 0){
                                while(1){
                                        memset(msg,0,sizeof(msg));
                              			sprintf(msg,"Welcome NO.%d client",mark);
                                        //6.write
                                        write(c_fd,msg,strlen(msg));
                                        sleep(3);
                                        }
                                }
                        //5.read
                        while(1){
                                memset(readBuf,0,sizeof(readBuf));
                                n_read = read(c_fd,readBuf,128);
                                if(n_read == -1 ){
                                        perror("read");
                                }else{
                                        printf("get message:%d,%s\n",n_read,readBuf);
                                }
                        }
                        break;
                }
        }
        return 0;
}

九. 搭建服务器存取文件

客户端:
1.获取服务器文件 get xxx 功能2.0
2.展示服务器有哪些文件 ls 功能1.0
3.进入服务器文件夹 cd xx 功能3.0
4.上传文件到服务器 put xx 功能4.0
本地:
1.lls 查看客户端本地文件 功能5.0
2.lcd 进入客户端文件夹 功能5.0

  • 18
    点赞
  • 69
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
### 回答1: 在 Linux 下编写 C 语言程序需要一个编译器,如 GCC。可以使用命令行工具编写代码,并使用 GCC 编译器编译代码。例如,在命令行中输入 "gcc -o programname programname.c" 可以将 programname.c 文件编译为可执行文件 programname。然后在命令行运行 "./programname" 即可运行编译后的程序。 ### 回答2: Linux下C语言编程是非常常见的一种开发环境与方式。Linux操作系统提供了完善的C语言开发工具链,包括编译器、调试工具、开发库等,因此在Linux下进行C语言编程是非常方便和高效的。 首先,Linux下最常用的C语言编译器是GNU编译器套装(GCC)。GCC是一个开源的编译器套件,支持多种编程语言,其中包括C语言。使用GCC编译器,可以将C语言源代码编译成可执行的机器代码,从而在Linux操作系统上运行。 其次,Linux提供了丰富的调试工具,如GNU调试器(GDB)。GDB是一个功能强大的调试工具,可以通过设置断点、查看变量值、跟踪程序执行流程来帮助开发人员进行代码调试。使用GDB可以快速定位并解决代码中的错误。 此外,Linux还提供了大量的开发库和工具,如标准C库(libc)、各种系统库和第三方库等。这些库和工具能够极大地提升C语言编程的效率和功能,开发人员可以利用这些库来实现各种功能,如文件操作、网络通信、图形界面等。 在Linux下进行C语言编程还有一个显著的优势就是开源社区的支持。Linux有庞大的开源社区,有着丰富的资源和经验,开发人员可以从中获取帮助和学习。在开源社区中,开发人员可以共享自己的代码、学习他人的经验,并且可以参与到各种开源项目中去,提升自己的技能和知识。 综上所述,Linux下C语言编程是非常强大和便利的。通过Linux提供的工具链、库和开源社区的支持,开发人员可以高效地进行C语言编程,实现各种功能和项目。 ### 回答3: Linux下的C语言编程是一种广泛应用的编程方式。Linux作为一种开源操作系统,在C语言编程方面具有许多优势和特点。 首先,Linux下的C语言编程可以充分利用Linux操作系统的强大功能和丰富的系统接口。通过使用Linux的系统调用接口,我们可以直接对文件、进程、网络等进行操作,实现更高级的功能。同时,Linux提供了许多方便的开发工具和库,比如GCC编译器、C库,使得C语言编程更加方便和高效。 其次,Linux下的C语言编程具有良好的可移植性。由于Linux操作系统的开源性质,C语言编程在Linux下编写的程序可以在其他操作系统上进行移植。这为开发者提供了更大的自由度和灵活性,使得他们能够更好地跨平台开发和移植应用程序。 另外,Linux下的C语言编程也提供了强大的调试和性能优化工具。开发者可以使用诸如gdb、valgrind等工具对C程序进行调试和性能分析,以找出潜在的问题并提高程序的效率。这些工具的存在大大提高了开发者对程序的控制和管理能力。 总结而言,Linux下的C语言编程是一种功能强大、可移植性高且开发工具丰富的编程方式。通过利用Linux操作系统的强大功能和丰富接口,开发者可以编写高效、稳定且可移植的应用程序。这使得Linux下的C语言编程成为了许多开发者的首选。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小强子!

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值