`
xdlliutao
  • 浏览: 37856 次
  • 性别: Icon_minigender_2
  • 来自: 北京
文章分类
社区版块
存档分类
最新评论

Linux入门培训教程 linux网络编程socket介绍

阅读更多
一.概念介绍

  网络程序分为服务端程序和客户端程序。服务端即提供服务的一方,客户端为请求服务的一方。但实际情况是有些程序的客户端、服务器端角色不是这么明显,即互为Linux培训

客户端和服务端。

  我们编写网络程序时,一般是基于TCP协议或者UDP协议进行网络通信的。兄弟连Linux培训小编整理:

  TCP:(Transfer Control Protocol)传输控制协议是一种面向连接的协议,当我们的网络程序使用这个协议的时候,网络可以保证我们的客户端和服务端之间的传输是可靠的。

  UDP:(User DatagramProtocol)用户数据报协议是一种非面向连接的协议, 这种协议并不能保证我们的网络程序的连接是可靠的。

  我们编写的网络程序具体采用哪一类协议,要视具体情况而定。比如,如果是大数据量的通信,而且对数据的完整性要求不是特别高,则可以采用UDP协议,以得到更快的传输速率。如果我们是要实现一些诸如文件传输、社交通讯之类的功能,就需要采用TCP协议通信,以保证传输的可靠性。

  二.初等网络函数介绍

  nt socket(int domain, inttype,int protocol)

  domain:说明我们网络程序所在的主机采用的通讯协族(AF_UNIX和AF_INET等).

  AF_UNIX只能够用于单一的Unix 系统进程间通信,

  而AF_INET是针对Internet的,因而可以允许在远程

  主机之间通信(当我们 man socket时发现 domain可选项是 PF_*而不是AF_*,因为glibc是posix的实现所以用PF代替了AF,

  不过我们都可以使用的).

  type:我们网络程序所采用的通讯协议(SOCK_STREAM,SOCK_DGRAM等)

  SOCK_STREAM表明我们用的是TCP 协议,这样会提供按顺序的,可靠,双向,面向连接的比特流.

  SOCK_DGRAM 表明我们用的是UDP协议,这样只会提供定长的,不可靠,无连接的通信.

  protocol:由于我们指定了type,所以这个地方我们一般只要用0来代替就可以了 socket为网络通讯做基本的准备.

  成功时返回文件描述符,失败时返回-1,看errno可知道出错的详细情况.

  int bind(int sockfd, structsockaddr *my_addr, int addrlen)

  sockfd:是由socket调用返回的文件描述符.

  addrlen:是sockaddr结构的长度.

  my_addr:是一个指向sockaddr的指针. 在中有sockaddr的定义

  struct sockaddr{

  unisgned short as_family;

  char sa_data[14];

  };

  不过由于系统的兼容性,我们一般不用这个头文件,而使用另外一个结构(struct sockaddr_in) 来代替.在中有sockaddr_in的定义

  struct sockaddr_in{

  unsigned short sin_family;

  unsigned short intsin_port;

  struct in_addr sin_addr;

  unsigned char sin_zero[8];

  }

  我们主要使用Internet所以

  sin_family一般为AF_INET,

  sin_addr设置为INADDR_ANY表示可以和任何的主机通信,

  sin_port是我们要监听的端口号.sin_zero[8]是用来填充的.

  bind将本地的端口同socket返回的文件描述符捆绑在一起.成功是返回0,失败的情况和socket一样

  int listen(int sockfd,intbacklog)

  sockfd:是bind后的文件描述符.

  backlog:设置请求排队的最大长度.当有多个客户端程序和服务端相连时, 使用这个表示可以介绍的排队长度.

  listen函数将bind的文件描述符变为监听套接字.返回的情况和bind一样.

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

  sockfd:是listen后的文件描述符.

  addr,addrlen是用来给客户端的程序填写的,服务器端只要传递指针就可以了. bind,listen和accept是服务器端用的函数,

  accept调用时,服务器端的程序会一直阻塞到有一个 客户程序发出了连接. accept成功时返回最后的服务器端的文件描述符,

  这个时候服务器端可以向该描述符写信息了. 失败时返回-1

  int connect(int sockfd,struct sockaddr * serv_addr,int addrlen)

  sockfd:socket返回的文件描述符.

  serv_addr:储存了服务器端的连接信息.其中sin_add是服务端的地址

  addrlen:serv_addr的长度

  connect函数是客户端用来同服务端连接的.成功时返回0,sockfd是同服务端通讯的文件描述符 失败时返回-1.

  更多函数请查看man …….

  int getaddrinfo(const char*node, const char *service,

  const struct addrinfo*hints,

  struct addrinfo **res);

  三.初等网络函数使用实例

  一个教科书式的服务器端程序流程为:

  建立套接字socket()--->将套接字绑定到ip地址bind()----->建立监听套接字listen()------>开始等待客户端请求accpet()

  详细代码如下:

  复制代码代码如下:

  #include <stdlib.h>

  #include <stdio.h>

  #include <errno.h>

  #include <string.h>

  #include <unistd.h>

  #include<sys/socket.h>

  #include<netinet/in.h>

  #include<sys/types.h>

  #include <netdb.h>

  int main(int argc, char*argv[])

  {

  int sockfd,connfd;

  struct sockaddr_in srvaddr;

  struct sockaddr_in cliaddr;

  int len,port;

  charhello[]="Hi,welcome to linux-code!\n";

  if((sockfd=socket(AF_INET,SOCK_STREAM,0))==-1){

  fprintf(stderr,"Socketerror:%s\n\a",strerror(errno));

  exit(1);

  }

  /* 服务器端填充 sockaddr结构 */

  bzero(&srvaddr,sizeof(structsockaddr_in));

  srvaddr.sin_family=AF_INET;

  srvaddr.sin_addr.s_addr=htonl(INADDR_ANY);

  srvaddr.sin_port=htons(1113);

  /* 捆绑sockfd描述符 */

  if(bind(sockfd,(structsockaddr *)(&srvaddr),sizeof(struct sockaddr))==-1){

  fprintf(stderr,"Binderror:%s\n\a",strerror(errno));

  exit(1);

  }

  /* 监听sockfd描述符 */

  if(listen(sockfd,5)==-1){

  fprintf(stderr,"Listenerror:%s\n\a",strerror(errno));

  exit(1);

  }

  len=sizeof(structsockaddr_in);

  while(1){ /* 服务器阻塞,直到客户程序建立连接 */

  if((connfd=accept(sockfd,(structsockaddr *)(&cliaddr),&len))==-1){

  fprintf(stderr,"Accepterror:%s\n\a",strerror(errno));

  exit(1);

  }

  fprintf(stderr,"Serverget connection from %s\n",inet_ntoa(cliaddr.sin_addr));

  if(write(connfd,hello,strlen(hello))==-1){

  fprintf(stderr,"WriteError:%s\n",strerror(errno));

  exit(1);

  }

  /* 这个通讯已经结束 */

  close(connfd);

  /* 循环下一个 */

  }

  close(sockfd);

  exit(0);

  }

  一个教科书式的客户端程序流程为:

  建立套接字socket()--->与服务器建立连接connect()

  详细代码如下:

  复制代码代码如下:

  #include <stdlib.h>

  #include <stdio.h>

  #include <errno.h>

  #include <string.h>

  #include <unistd.h>

  #include<sys/socket.h>

  #include<netinet/in.h>

  #include <sys/types.h>

  #include <netdb.h>

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

  int sockfd; char buf[1024];

  struct sockaddr_in srvaddr;

  struct hostent *phost; intnbytes;

  if(argc!=3){

  fprintf(stderr,"Usage:%s<IP> <portnumber>\a\n",argv[0]);

  exit(1);

  }

  /* 客户程序开始建立 sockfd描述符 */

  if((sockfd=socket(AF_INET,SOCK_STREAM,0))==-1){

  fprintf(stderr,"socketError:%s\a\n",strerror(errno));

  exit(1);

  }

  /* 客户程序填充服务端的资料 */

  bzero(&srvaddr,sizeof(srvaddr));

  srvaddr.sin_family=AF_INET;

  srvaddr.sin_port=htons(atoi(argv[2]));

  if (inet_pton(AF_INET,argv[1], &srvaddr.sin_addr) <= 0){

  fprintf(stderr,"inet_ptonError:%s\a\n",strerror(errno));

  exit(1);

  }

  /* 客户程序发起连接请求 */

  if(connect(sockfd,(structsockaddr *)(&srvaddr),sizeof(struct sockaddr))==-1){

  fprintf(stderr,"connectError:%s\a\n",strerror(errno));

  exit(1);

  }

  /* 连接成功了 */

  if((nbytes=read(sockfd,buf,1024))==-1){

  fprintf(stderr,"readError:%s\n",strerror(errno));

  exit(1);

  }

  buf[nbytes]='\0';

  printf("received data:%s\n",buf);

  /* 结束通讯 */

  close(sockfd);

  exit(0);

  }

  四.上述程序存在的问题

  先运行上述程序的服务端程序,再运行客户端程序,可以得到如下结果:

  服务器端结果:

  viidiot@ubuntu:~/code $./srv

  Server get connection from192.168.1.153

  Server get connection from127.0.0.1

  Server get connection from192.168.1.153

  客户器端结果:

  viidiot@ubuntu:~/code $./cli 192.168.1.153 1113

  received data:Hi,welcome tolinux-code!

  我们完成了一个简单的网络通信程序,该程序使用的io模型为同步(synchronous)阻塞(blocking)。服务器端调用accept(),write()等函数,如果没有客户端连接过来或者相应的文件描述符没有准备好写,程序就会在那里死死的等待,什么事情也不干。在实际应用中,这类程序是很少出现的。实际中使用的都是异步io模型。



分享到:
评论

相关推荐

    Linux网络编程教程pdf完整版

    1. **网络编程基础**:首先,书中会介绍网络通信的基本概念,包括TCP/IP协议栈、套接字(socket)接口、端口号以及网络地址(如IPv4和IPv6)等。了解这些基础知识是进行网络编程的前提。 2. **套接字编程**:作为...

    Linux网络编程socket错误码分析

    Linux 网络编程 socket 错误码分析 在 Linux 网络编程中,socket 函数可能会返回多种错误码,这些错误码提供了有价值的信息,可以帮助开发者诊断和处理网络编程中的问题。本文档总结了常见的 socket 错误码及其处理...

    LinuxSocket网络编程系列文档合集

    教程名称:Linux Socket网络编程系列文档合集课程目录:【】Linux 网络编程入门教程 clown【】linux系统分析与高级编程技术【】Linux网络编程(10)-- 原始套接字【】Linux网络编程(7)--7TCPIP协议【】Linux网络编程--...

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

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

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

    Linux网络编程是操作系统领域中的一个重要话题,特别是...通过深入学习以上知识点,并结合《Linux网络编程》这样的入门书籍,你可以逐步掌握在Linux环境下进行网络编程的技能,从而开发出高效、稳定、安全的网络应用。

    linux 编程教程 -- linux下编程入门

    Linux编程教程——Linux下编程入门 在Linux操作系统中进行编程是一项重要的技能,尤其对于系统级开发者和软件工程师来说。Linux提供了丰富的开发环境和工具,支持多种编程语言,如C、C++、Python、Java等。本教程将...

    linux下socket网络编程

    在Linux操作系统中,Socket网络编程是构建网络应用的基础,它允许不同进程间的通信,甚至跨越不同的计算机。在C语言环境中,我们通常使用标准的Berkeley Sockets API来实现这一目标。本篇将深入探讨Linux下C语言实现...

    Linux socket 编程入门

    总结起来,Linux Socket编程入门的关键在于理解网络通信的基本原理和TCP协议的特点,然后利用套接字API实现服务器端和客户端的交互。通过创建一个简单的echo服务器,我们可以更好地理解TCP服务器的工作流程,为...

    linux系统下socket编程详解教程

    以下是对标题“Linux系统下Socket编程详解教程”及描述“Linux下socket编程,适合初次学习网络编程的学者”的深入解析与扩展。 ### 网络基础 在开始探讨Socket编程之前,我们先简要回顾网络基础知识,这有助于更好...

    Linux环境下的网络编程.pdf

    Linux 作为一个单一内核的操作系统,协议栈的实现嵌在系统内核中,本文分析了 TCP/IP 协议的基本原理以及 Linux 中的 TCP/IP 网络层次结构,重点介绍了 Linux 环境下的 socket 编程。 Linux 环境下的网络编程是指在...

    基于Linux的Socket网络编程的性能优化.pdf

    Linux Socket网络编程性能优化 基于Linux的Socket网络编程的性能优化是指在Linux操作系统环境下,通过Socket网络编程来实现高性能的网络传输。Socket是Linux操作系统中的一种网络编程接口,允许程序员在不同的主机...

    linux网络基础和网络编程

    本文将深入探讨这个主题,从Linux网络的基础知识开始,逐步讲解到Socket编程以及如何实现高并发服务器。 1. Linux网络基础: - 网络模型:Linux遵循OSI七层网络模型(物理层、数据链路层、网络层、传输层、会话层...

    Linuxsocket编程入门[参照].pdf

    本教程将从基础开始,详细介绍 Linux Socket 编程的入门知识,包括 TCP server 端的实现。 一、Socket 编程的概念 Socket 编程是一个庞大的体系,包括TCP/IP、网络层、运输层、应用层等多个层次。Socket 编程的...

    C和C++项目源码Clion上创建的linux socket网络编程远程控制树莓派的led灯.zip

    C和C++项目源码-Clion上创建的linux socket网络编程远程控制树莓派的led灯.zipC和C++项目源码-Clion上创建的linux socket网络编程远程控制树莓派的led灯.zipC和C++项目源码-Clion上创建的linux socket网络编程远程...

    基于Linux的Socket网络编程的性能优化

    本文将详细介绍在Linux环境下Socket网络编程的基本原理、流程以及如何通过一系列优化措施提升其性能。 #### 二、Socket概述 在Linux系统中,网络编程主要通过Socket接口实现,这是一种特殊的I/O操作形式,其实质是...

    Linux下使用C++进行Socket编程

    Linux下使用C++进行Socket编程是一门涉及网络通信的高级技术。在Linux操作系统中,Socket编程通常采用C语言,因为传统的GNU C库提供了丰富的Socket API函数,但这些函数是面向过程设计的,没有面向对象的封装,使用...

    实用socket网络编程教程

    实用socket网络编程教程实用socket网络编程教程实用socket网络编程教程实用socket网络编程教程

    第21章Linux网络通信高级编程Socket.pdf

    【Linux网络通信高级编程Socket】章节主要探讨了在Linux环境下如何进行高级的网络通信编程,特别是使用Socket进行TCP/IP通信。Socket是网络编程的核心概念,它代表了一个通信端点,结合IP地址和端口号,用于标识网络...

    sniffer 网络编程 socket

    sniffer 网络编程 socket sniffer 网络编程 socket sniffer 网络编程 socket sniffer 网络编程 socket sniffer 网络编程 socket sniffer 网络编程 socket sniffer 网络编程 socket sniffer 网络编程 socket

Global site tag (gtag.js) - Google Analytics