`

linux网络编程

阅读更多

实现一个简单的Client/Server通信的程序:

服务器端和客户端的通信过程: 

1. 服务器端:

1) 服务器端创建套接字(socket() )

2) 服务器端将套接字绑定到本机端口( bind() )

3) 服务器端的套接字转化为监听套接字( listen() )

4) 服务器端阻塞等待客户端发送信息到服务器( accept() )

5) 服务器端读取客户端的数据( read() )

6) 服务器端向客户端发送数据( write() )

7) 关闭连接(close() )

 

2.客户端:

1) 创建客户端套接字(socket() )

2) 向服务器端请求连接 (connect() )

3) 向服务器端写数据 (writ())

4) 接收服务器端的数据 (read ())

5) 关闭连接 (close())

 

 

编程常用数据结构和API

1)定义套接字地址结构

# include<linux/socket.h>

 

struct sockaddr{                     //  通用的套接字地址

    unsigned short sa_family ;  //  地址类型 AF_XXX

    char sa_data[14];                // 协议地址

}

 

struct sockaddr_in{                    //TCP/IP族的套接字地址

     unsigned short sin_family;     //地址类型

     unsigned short int sin_port ;  //端口号

     struct in_addr sin_addr;         //IP地址

     unsigned char sin_zero[8];     //填充字节

 

 

struct in_addr{     //  IP地址

      unsigned long s_addr;

 

}

 

 

 

设置服务器地址的一个示例代码如下:

 

struct sockaddr_in sock;

memset(&sock,0,sizeof(sockaddr_in));

sock.sin_family=AF_INET;

sock.sin_port=80;

inet_aton("127.0.0.1",&sock.sin_addr)

 

 

其中,inet_aton 和 memset函数的定义如下:

#include<netinet/in.h>

#include<arpa/inet.h>

int inet_aton(const char *cp,struct in_addr *inp) //将cp所指向的字符串转化为二进制的网络字节顺序的IP地址

memset(void *s,int c,size_t n)  //将s所指向的前n个字节赋成参数c所指定的值

 

 

2)创建套接字

#include<sys/types.h>

#include<sys/socket.h>

 

int socket(int domain,int type,int protocol)

 

// domain: AF_INET。。。

// type: 套接字类型 (SOCK_STREAM: TCP流套接字  |  SOCK_DGRAM:  UDP流套接字 )

// protocol =0                             

 

 

3) 绑定套接字(将创建套接字和服务器地址绑定)

#include <sys/types.h>

#include <sys/socket.h>

int bind (int sockfd, struct sockaddr * my_addr, socklen_t addlen)

 

 

4) 建立监听(将套接字转换为监听套接字)

#include<sys/socket.h>

int listen(int s, int backlog)

 

//s: 套接字

//backlog : 定义连接请求队列的长度

 

 

5) 服务器端阻塞等待客户端连接请求

#include <sys/types>

#include <sys/socket>

int accept(int s, struct sockaddr_in * addr, socket_t addrlen);

 

 

6) 客户端请求连接

 

#inlcude <sys/types.h>

#inlcude <sys/socket.h>

 

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

 

//sockfd:套接字

//serv_addr :服务器地址结构体

//addrlen : 地址结构体的长度

 

 

7) 接收数据

#inlcude <sys/types.h>

#inlcude <sys/socket.h>

 

size_t recv(int s, void * buf, size_t len, int flags);

 

//返回发送数据的长度

 

 

8) 发送数据

 

#inlcude <sys/types.h>

#inlcude <sys/socket.h>

 

size_t send(int s, const void* msg, size_t  len, int flags);

//返回发送数据的长度

 

 

 

下面来看三个实例~

1) 基于TCP 协议的服务器端和客户端通信程序:

 

///服务器端  my_server.c

 

#include <sys/type.h>

#include <sys/socket.h>

#include <stdio.h>

#include <string.h>

#include <netinet/in.h>

#include <unistd.h>

#include <arpa/inet.h>

#include <errno.h>

#include "my_recv.h" //自定义头文件

 

#define SERV_PORT    4507   // 服务器端口

#define LISTENQ    12            // 连接请求队列的最大长度

 

 

//发送数据

void send_data(int conn_fd,const char* string)

{

     if( send(conn_fd,srtring,strlen(string),0)<0) {

         // my_err("send",__LINE__);  // my_err 函数在my_recv.h 中声明

         printf("send error\n");

         exit(1);

      }

}

 

 

int main() {

   int sock_fd,conn_fd;

   int optval;

   int ret;

   int name_num;

   pit_t pid;

   socklen_t cli_len;

   struct sockaddr_in cli_addr,serv_addr;

   char recv_buf[128];

  

   //创建TCP套接字

   sock_fd = socket(AF_INET,SOCK_STREAM,0);

   if(sock_fd<0){

        my_err("socket",__LINE__);

   }

 

 

   //设置该套接字使之可以重新绑定端口

   optval=1;

   if(setsockopt(sock_fd,SOL_SOCKET,SO_REUSEADDR,(void *)optval,sizeof(int)<0){

      //  my_err("setsockopt",__LINE__);

         printf("setsockopt error\n");

         exit(1);

   }

 

   //初始化服务器端地址结构

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

   serv_addr.sin_family=AF_INET;

   serv_addr.sin_port = htons(SERV_PORT);

   serv_addr.sin_addr.s_addr=htonl(INADDR_ANY);

 

 

   //将套接字绑定到本地端口

   if (bind(sock_fd,(struct sockaddr *)&serv_addr, sizeof(struct sockaddr_in))<0){

       //my_err("bind",__LINE__);

          printf("bind error\n");

          exit(1);

   }

 

 

   //将套接字转化为监听套接字

   if (listen(sock_fd,LISTENQ)<0){

      //my_err("listen",__LINE__);

         printf("listen error\n");

         exit(1);

   }

 

 

   cli_len=sizeof(struct sockaddr_in);

   while(1){

     //主进程通过accept阻塞等待客户端的连接请求,并返回连接套接字用于收发数据

       conn_fd= accept(sock_fd,(struct sockaddr*)&cli_addr,&cli_len);

       if(conn_fd<0){

            //my_err("accept",__LINE__);

             printf("accept error\n");

             exit(1);

       }

 

    //创建子进程处理接收到的连接请求

    if ((pid=fork())==0){   //子进程

         while(1){

               if((ret=recv(conn_fd,recv_buf,sizeof(recv_buf),0))<0)<0){

                    perror("recv");

                    exit(1);

               }

               printf("the received data is:%s \n",recv_buf);

               send_data(conn_fd,"I've just received data: %s\n",recv_buf); 

          }     

          close(sock_fd);

          close(conn_fd);

          exit(0);  //结束子进程

     }

     return 0;

 

}

 

 

///客户端 myclient.c

 

#include<sys/socket.h>

#include<netinet/in.h>

#include<stdio.h>

#include<stdlib.h>

#include<unistd.h>

#include<string.h>

#include<sys/types.h>

#include<errno.h>

#include<arpa/inet.h>

 

int main(int argc,char **argv){

     int i;

     int ret;

     int conn_fd;

     int serv_port=4507;

     char *strIP="127.0.0.1";

     struct sockaddr_in serv_addr;

     char  input_buf[BUFSIZE]="Hello Joan!";

     char  recv_buf[BUFSIZE];

    

 

     //初始化服务器端地址结构

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

     serv_addr.sin_family=AF_INET;

     serv_addr.sin_port=htons(serv_port);

     inet_aton(strIP,&serv_addr.sin_addr);

    

 

    //创建一个TCP套接字

    conn_fd=socket(AF_INET,SOCK_STREAM,0);

    if(conn_fd<0){

         printf("client socket error\n");

         exit(1);

     }

   

    //向服务器发送连接请求

    if(connect(conn_fd,(struct sock_addr *)&serv_addr,sizeof(sock_addr))<0){

          printf("client connect error\n");

          exit(1);

    }

   

    //向服务器发送数据

    if(send(conn_fd,input_buf,strlen(input_buf),0)<0){

         printf("client send error\n");

          exit(1);

    }

         

    // 读取服务器发送的数据

    if((ret=recv(conn_fd,recv_buf,sizeof(recv_buf),0)<0){

          printf("data too long\n");

          exit(1);

    }

    printf("the received data from server is: %s\n",recv_buf);

 

   close(conn_fd);

   return 0;

 

}

               

  

    

2) 实现将一个文件分割为N份发送到服务器端,在服务器端再重组文件的程序:

 

 

 

 

3) 实现一个简单的端口扫描程序:

// 基于UDP 协议的服务器端和客户端通信程序: 

 
分享到:
评论

相关推荐

    Linux网络编程 Linux网络编程.TXT

    ### Linux网络编程核心知识点解析 #### 一、网络模型与协议概述 - **OSI七层模型**:从物理层到应用层,详述了数据在网络中的传输过程。 - **Internet模型**:简化了OSI模型,将网络分为四层:应用层、传输层、...

    Linux网络编程,包括tcp/upd,select/poll/epoll/pdf

    linux网络编程 pdf # Linux网络编程基础 Linux网络编程是指在Linux操作系统上开发网络应用程序的过程。它主要涉及到TCP/UDP协议以及select/poll/epoll等多路复用技术。 TCP/UDP协议是网络通信的基础,其中TCP协议...

    Linux网络编程教程pdf完整版

    《Linux网络编程教程》这本书是Linux系统中进行网络编程的重要参考资料。它涵盖了广泛的知识点,旨在帮助读者理解和掌握如何在Linux环境下开发网络应用程序。以下是对这些主题的详细阐述: 1. **网络编程基础**:...

    linux网络编程(linux网络编程入门书籍)

    Linux网络编程是操作系统领域中的一个重要话题,特别是在服务器端软件开发中。这门技术涉及如何在Linux环境下编写程序,实现网络通信,包括TCP/IP协议栈、套接字编程、并发服务处理等多个方面。以下是对这个主题的...

    Linux网络编程.pdf

    《Linux网络编程》一书深入探讨了在网络环境中利用Linux操作系统进行高效编程的技术和理论,尤其适合于希望深入了解网络编程原理及实践的读者。本书不仅涵盖了网络编程的基础理论,还提供了丰富的示例代码,帮助读者...

    linux 网络编程.pdf

    linux 网络编程.pdf

    Linux网络编程(第2版)随书源代码.rar

    《Linux网络编程(第2版)》是一本深入探讨Linux环境下网络编程的权威书籍,它为读者揭示了网络通信的核心原理和技术。随书附带的源代码是学习和实践网络编程的重要参考资料,可以帮助读者更直观地理解书中的理论...

    Linux网络编程.rar

    linux网络编程

    Linux网络编程一步一步学.rar

    在IT领域,Linux网络编程是构建高性能服务器和网络应用程序的核心技术。这个压缩包"Linux网络编程一步一步学.rar"提供了一套全面的学习资源,包括一本由刘杰编辑的PDF书籍和三个关于Linux网络编程基础的DOC文档。...

    Linux网络编程_张斌.rar

    《Linux网络编程》是张斌先生的一部专著,深入浅出地讲解了在Linux操作系统环境下进行网络编程的各种技术和实践。这本书涵盖了网络编程的基础概念、协议、API使用以及实际问题的解决方案,对于想要掌握Linux网络编程...

    linux网络编程基础

    Linux网络编程是操作系统领域的核心技能之一,特别是在服务器端软件开发中。本教程主要关注Linux环境下的网络编程基础知识,包括UDP(用户数据报协议)和TCP(传输控制协议)的通信模型。下面将详细介绍这两个协议...

    Linux网络编程.pdf.rar

    《Linux网络编程》这本书是针对初学者的一份详尽指南,涵盖了从基础到高级的Linux网络编程知识。在Linux系统中进行网络编程是理解和构建网络应用程序的关键,这涉及到socket编程、网络协议、并发处理等多个方面。 ...

    linux网络编程代码

    Linux网络编程是操作系统与网络应用开发的重要组成部分,它涉及到如何在Linux环境下利用系统调用进行网络数据传输,创建服务器和客户端程序,以及处理各种网络协议。在这个领域,开发者需要掌握Socket编程、网络协议...

    linux网络编程-源代码.rar

    《Linux网络编程》一书是IT领域中关于操作系统与网络通信的经典教材,它深入探讨了在Linux环境下如何进行网络编程,涵盖了从低级socket接口到高级应用层协议的实现。这个压缩包“linux网络编程-源代码.rar”包含了该...

    Linux网络编程1.pdf

    Linux网络编程是计算机网络领域的一个重要组成部分,主要涉及操作系统级别的编程技术,用于实现网络应用软件的开发。以下是关于Linux网络编程的一些核心知识点,从OSI模型、进程间通信、套接字编程、到安全性和高级...

    linux网络编程 代码 加电子书

    Linux网络编程是操作系统和计算机网络领域的一个重要主题,它涵盖了如何在Linux环境下设计、实现和优化网络应用程序。在这个领域,开发者需要理解操作系统内核如何处理网络数据,以及如何利用各种API进行进程间通信...

    Linux网络编程pdf

    3. **Linux网络编程**: 这部分可能涵盖了网络协议栈、套接字编程、网络服务开发等内容。开发者会学习如何使用socket API进行客户端和服务端的编程,理解TCP/IP协议族的工作原理,包括TCP和UDP连接的建立与关闭,...

Global site tag (gtag.js) - Google Analytics