涉及到的数据结构:

  下面首先介绍两个重要的数据类型:sockaddr和sockaddr_in,这两个结构类型都是用来保存socket地址信息的

定义如下所示:

struct sockaddr {
unsigned short sa_family; /*地址族*/
char sa_data[14];     /*14字节的协议地址,包含该socket的IP地址和端口号*/
};
struct sockaddr_in {
short int sa_family; /*地址族*/
unsigned short int sin_port; /*端口号*/
struct in_addr sin_addr; /*IP地址*/
unsigned char sin_zero[8]; /*填充0 以保持与struct sockaddr同样大小*/
};

  这两个数据类型是等效的,可以相互转化,通常sockaddr_in数据类型使用更为方便。在建立socketaddr或sockaddr_in后,就可以对该socket进行适当的操作了。
  如表所示列出了该结构sa_family字段可选的常见值:

涉及到的函数:

1. socket函数:创建套接字

 socket函数标准调用格式说明如下:

#include <sys/types.h>
#include <sys/socket.h> int socket(int domain, int type, int protocol);  //成功返回一个正整数,失败返回-1
  • domain: 套接字的协议族,如:AF_INET(IPv4协议)、AF_INET6(IPv6协议)、AF_UNIX、AF_LOCAL(本地交互协议)等等
  • type: 指定当前的套接字类型,如:SOCK_STREAM(数据流)、SOCK_DGRAM(数据报)、SOCK_RAW(原始套接字)等等
  • protocol: 在使用原始套接字之外通常设置为0,表示使用默认协议

2. bind函数:绑定套接字

 bind函数标准调用格式说明如下:

#include <sys/types.h>
#include <sys/socket.h> int bind(int sockfd, const struct socketaddr *addr, socklen_t addrlen);  //成功返回0,否则返回-1
  • sockfd: 使用socket函数创建的套接字对应的套接字描述符
  • addr: 本地地址
  • addrlen: 套接字对应的地址结构长度

3. connect函数:建立连接

 connect函数标准调用格式说明如下:

#include <sys/types.h>
#include <sys/socket.h> int connect(int sockfd, const struct socketaddr *addr, socklen_t addrlen);  //成功返回0,否则返回-1
  • sockfd: 使用socket函数创建的套接字对应的套接字描述符
  • addr: 指定远程服务器的套接字地址,包括服务器的IP地址和端口号
  • addrlen: 该套接字对应的地址结构长度

4. listen函数:倾听模式

 listen函数标准调用格式说明如下:

#include <sys/types.h>
#include <sys/socket.h> int listen(int sockfd, int backlog);  //成功返回0,否则返回-1
  • sockfd: 使用socket函数创建的套接字对应的套接字描述符
  • backlog: 设置请求队列的最大长度

5. accept函数:接收连接

 accept函数标准调用格式说明如下:

#include <sys/types.h>
#include <sys/socket.h> int accept(int sockfd, struct socketaddr *addr, socklen_t *addrlen);  
  • sockfd: 使用socket函数创建的套接字对应的套接字描述符
  • addr: 指向一个Internet套接字地址结构的指针
  • addrlen: 指向一个整型变量的指针

6. close函数:关闭连接

 close函数标准调用格式说明如下:

#include <unistd.h>

int close(int fd);

7. send和recv函数:发送和接收数据

 send和recv函数标准调用格式说明如下:

#include <sys/types.h>
#include <sys/socket.h> ssize_t send(int sockfd, const void *buf, size_t len, int flags);  //成功返回实际发送的字节数,否则返回-1
ssize_t recv(int sockfd, void *buf, size_t len, int flags);      //成功返回实际接收的字节数,否则返回-1
  • sockfd: 使用socket函数创建的套接字对应的套接字描述符
  • buf: 待发送或接收数据的缓存区
  • len: 待发送数据的缓存区的长度或接收数据的长度
  • flags: 用于指定消息的传送类型

【应用实例】 ——   Linux 系统 TCP网络协议编程

  通过一个简单的 tcp 服务器端,接收客户端的连接请求,并接受客户端发来的信息。

  服务器端和客户端使用TCP协议的流程图如图:

  

图 - 使用TCP协议socket编程流程图

  其中服务器端首先建立起socket,然后调用本地端口的绑定,接着就开始与客户端建立联系,并接收客户端发送的消息。客户端则在建立socket之后调用connect函数来建立连接。

服务器端的源代码如下所示:

// server.c
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <time.h>
#include <stdio.h>
#include <string.h> #define PORT 5555 //服务器接听端口号
#define BUF_SIZE 1024 //缓存区大小 int main(int argc, char *argv[])
{
int ret;
char buf[BUF_SIZE];
int sockfd;
int clientfd;
struct sockaddr_in addr;
struct sockaddr_in client_addr;
int length = sizeof(client_addr); //创建套接字
sockfd = socket(AF_INET, SOCK_STREAM, 0);
if( sockfd == -1 )
{
printf("socket fail...");
return 1;
}
//绑定套接字
bzero(&addr, sizeof(struct sockaddr));
addr.sin_family = AF_INET; //IPv4
addr.sin_port = htons(PORT); //设定端口号
addr.sin_addr.s_addr = htonl(INADDR_ANY); //本地IP地址
ret = bind(sockfd, (struct sockaddr*)(&addr), sizeof(struct sockaddr));
if( ret == -1 )
{
printf("bind fail...");
return 1;
}
//监听网络端口
ret = listen(sockfd, 5);
if(ret == -1)
{
printf("listen fail...");
return 1;
}
while(1)
{
//接收连接请求
clientfd = accept(sockfd, (struct sockaddr*)(&client_addr), &length);
if(clientfd == -1)
{
printf("accept fail...");
return 1;
} while(1)
{
bzero(buf, sizeof(buf)); //清空缓存区
//接收数据
recv(clientfd, buf, sizeof(buf), 0);
printf("recv: %s\n", buf);
sleep(2);
}
close(clientfd);
}
return 0;
}

客户端的源代码如下所示:

// client.c
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <time.h>
#include <stdio.h>
#include <string.h> #define PORT 5555
#define BUF_SIZE 1024 int main(int argc, char *argv[])
{
int ret;
char buf[BUF_SIZE];
int sockfd;
struct sockaddr_in addr; //创建套接字
sockfd = socket(AF_INET, SOCK_STREAM, 0);
if( sockfd == -1 )
{
printf("socket fail...");
return 1;
}
//建立连接
bzero(&addr, sizeof(struct sockaddr));
addr.sin_family = AF_INET;
addr.sin_port = htons(PORT);
addr.sin_addr.s_addr = htonl(INADDR_ANY); //使用回环地址 127.0.0.1
ret = connect(sockfd, (struct sockaddr*)(&addr), sizeof(struct sockaddr));
if( ret == -1 )
{
printf("connect fail...");
return 1;
} while(1)
{
bzero(buf, sizeof(buf));
printf("send: ");
scanf("%s", buf);
send(sockfd, buf, strlen(buf), 0); //发送数据
sleep(1);
} close(sockfd);
return 0;
}

  

嵌入式Linux 网络编程的更多相关文章

  1. Linux网络编程&内核学习

    c语言: 基础篇 1.<写给大家看的C语言书(第2版)> 原书名: Absolute Beginner's Guide to C (2nd Edition) 原出版社: Sams 作者: ...

  2. 【深入浅出Linux网络编程】 "开篇 -- 知其然,知其所以然"

    [深入浅出Linux网络编程]是一个连载博客,内容源于本人的工作经验,旨在给读者提供靠谱高效的学习途径,不必在零散的互联网资源中浪费精力,快速的掌握Linux网络编程. 连载包含4篇,会陆续编写发出, ...

  3. 【linux草鞋应用编程系列】_5_ Linux网络编程

    一.网络通信简介   第一部分内容,暂时没法描述,内容实在太多,待后续专门的系列文章.   二.linux网络通信     在linux中继承了Unix下“一切皆文件”的思想, 在linux中要实现网 ...

  4. Linux 网络编程(IO模型)

    针对linux 操作系统的5类IO模型,阻塞式.非阻塞式.多路复用.信号驱动和异步IO进行整理,参考<linux网络编程>及相关网络资料. 阻塞模式 在socket编程(如下图)中调用如下 ...

  5. linux网络编程 no route to host 解决方案

    linux网络编程 no route to host 解决方案 [整合资料] (2013-05-13 21:38:12) 转载▼ 标签: net iptables it 分类: Linux 参考资料h ...

  6. linux网络编程-(socket套接字编程UDP传输)

    今天我们来介绍一下在linux网络环境下使用socket套接字实现两个进程下文件的上传,下载,和退出操作! 在socket套接字编程中,我们当然可以基于TCP的传输协议来进行传输,但是在文件的传输中, ...

  7. linux网络编程_1

    本文属于转载,稍有改动,以利于学习. (一)Linux网络编程--网络知识介绍 Linux网络编程--网络知识介绍客户端和服务端         网络程序和普通的程序有一个最大的区别是网络程序是由两个 ...

  8. Linux网络编程入门 (转载)

    (一)Linux网络编程--网络知识介绍 Linux网络编程--网络知识介绍客户端和服务端         网络程序和普通的程序有一个最大的区别是网络程序是由两个部分组成的--客户端和服务器端. 客户 ...

  9. Linux网络编程必看书籍推荐

    首先要说讲述计算机网络和TCP/IP的书很多. 先要学习网络知识才谈得上编程 讲述计算机网络的最经典的当属Andrew S.Tanenbaum的<计算机网络>第五版,这本书难易适中. &l ...

随机推荐

  1. EasingAnimation

    EasingAnimation https://github.com/YouXianMing/EasingAnimation This class is used for Easing animati ...

  2. Python学习---django惰性机制

    Django惰性机制 所谓惰性机制:Publisher.objects.all()或者.filter()等都只是返回了一个QuerySet(查询结果集对象),它并不会马上执行sql,而是当调用Quer ...

  3. CC2530 LED灯控制

      有三个寄存器 分别是功能寄存器.方向寄存器.配置寄存器 功能寄存器 通用 I/O口 说的就是一般的I/O口,可以输出高低电平 为外设IO 例如摄像头或者打印机他们具体实现某些功能(拍照或打印文档) ...

  4. Asp.Net MVC 开发技巧(一)

    开发程序时的流程: 1.设计数据模型. 数据模型最为重要,不仅关系到数据的存储,同时程序的可扩展性,效率也受影响,甚至决定开发工作量.所以要极其认真的设计数据库的表和相关字段. 建完基本的数据模型后, ...

  5. Android studio ocr初级app开发问题汇总(含工程代码)

    博客第一篇文章,稍作修改,增加文字介绍 开发目的 最近由于某些需求,需要在Android手机端实现OCR功能,大致为通过手机照相,识别出相片中的中文信息字段.但是由于新手光环+流程不熟悉,遇到了各种各 ...

  6. swift 数组部分排序

    数组自带排序函数,如果想实现部分排序,先对数组进行部分截取,然后对截取部分替换位排序好的子序列 var nums = [,,,,,,] var sub = nums[...] nums.replace ...

  7. oracle中RAW数据类型

    近日在研究v$latch视图时,发现一个从未见过的数据类型.v$latch 中ADDR属性的数据类型为RAW(4|8)  同时也发现v$process中的ADDR属性的数据类型也为RAW(4|8).于 ...

  8. android 智能指针的学习先看邓凡平的书扫盲 再看前面两片博客提升

    android 智能指针的学习先看邓凡平的书扫盲 再看前面两片博客提升

  9. HTML5 拖放、交换位置

    设置元素为可拖放 draggable 属性设置为 true: <img draggable="true" /> 拖动什么 - ondragstart 和 setData ...

  10. BZOJ 2440 完全平方数 莫比乌斯反演模板题

    题目链接: https://www.lydsy.com/JudgeOnline/problem.php?id=2440 题目大意: 求第k个无平方因子的数 思路: 二分答案x,求1-x中有多少个平方因 ...