linux下socket编程常用头文件

合集下载

linux串口编程参数配置详解

linux串口编程参数配置详解

linux串口编程参数配置详解1.linux串口编程需要的头文件#include <stdio.h> //标准输入输出定义#include <stdlib.h> //标准函数库定义#include <unistd.h> //Unix标准函数定义#include <sys/types.h>#include <sys/stat.h>#include <fcntl.h> //文件控制定义#include <termios.h> //POSIX中断控制定义#include <errno.h> //错误号定义2.打开串口串口位于/dev中,可作为标准文件的形式打开,其中:串口1 /dev/ttyS0串口2 /dev/ttyS1代码如下:int fd;fd = open(“/dev/ttyS0”, O_RDWR);if(fd == -1){Perror(“串口1打开失败!”);}//else//fcntl(fd, F_SETFL, FNDELAY);除了使用O_RDWR标志之外,通常还会使用O_NOCTTY和O_NDELAY这两个标志。

O_NOCTTY:告诉Unix这个程序不想成为“控制终端”控制的程序,不说明这个标志的话,任何输入都会影响你的程序。

O_NDELAY:告诉Unix这个程序不关心DCD信号线状态,即其他端口是否运行,不说明这个标志的话,该程序就会在DCD信号线为低电平时停止。

3.设置波特率最基本的串口设置包括波特率、校验位和停止位设置,且串口设置主要使用termios.h头文件中定义的termios结构,如下:struct termios{tcflag_t c_iflag; //输入模式标志tcflag_t c_oflag; //输出模式标志tcflag_t c_cflag; //控制模式标志tcflag_t c_lflag; //本地模式标志cc_t c_line; //line disciplinecc_t c_cc[NCC]; //control characters}代码如下:int speed_arr[] = { B38400, B19200, B9600, B4800, B2400, B1200, B300, B384 00, B19200, B9600, B4800, B2400, B1200, B300, };int name_arr[] = {38400, 19200, 9600, 4800, 2400, 1200, 300, 38400, 19200, 9 600, 4800, 2400, 1200, 300, };void SetSpeed(int fd, int speed){int i;struct termios Opt; //定义termios结构if(tcgetattr(fd, &Opt) != 0){perror(“tcgetattr fd”);return;}for(i = 0; i < sizeof(speed_arr) / sizeof(int); i++){if(speed == name_arr[i]){tcflush(fd, TCIOFLUSH);cfsetispeed(&Opt, speed_arr[i]);cfsetospeed(&Opt, speed_arr[i]);if(tcsetattr(fd, TCSANOW, &Opt) != 0){perror(“tcsetattr fd”);return;}tcflush(fd, TCIOFLUSH);}}}注意tcsetattr函数中使用的标志:TCSANOW:立即执行而不等待数据发送或者接受完成。

Linux的SOCKET编程详解

Linux的SOCKET编程详解

Linux的SOCKET编程详解1. 网络中进程之间如何通信进程通信的概念最初来源于单机系统。

由于每个进程都在自己的地址范围内运行,为保证两个相互通信的进程之间既互不干扰又协调一致工作,操作系统为进程通信提供了相应设施,如UNIX BSD有:管道(pipe)、命名管道(named pipe)软中断信号(signal)UNIX system V有:消息(message)、共享存储区(shared memory)和信号量(semaphore)等.他们都仅限于用在本机进程之间通信。

网间进程通信要解决的是不同主机进程间的相互通信问题(可把同机进程通信看作是其中的特例)。

为此,首先要解决的是网间进程标识问题。

同一主机上,不同进程可用进程号(process ID)唯一标识。

但在网络环境下,各主机独立分配的进程号不能唯一标识该进程。

例如,主机A赋于某进程号5,在B机中也可以存在5号进程,因此,“5号进程”这句话就没有意义了。

其次,操作系统支持的网络协议众多,不同协议的工作方式不同,地址格式也不同。

因此,网间进程通信还要解决多重协议的识别问题。

其实TCP/IP协议族已经帮我们解决了这个问题,网络层的―ip地址‖可以唯一标识网络中的主机,而传输层的―协议+端口‖可以唯一标识主机中的应用程序(进程)。

这样利用三元组(ip地址,协议,端口)就可以标识网络的进程了,网络中的进程通信就可以利用这个标志与其它进程进行交互。

使用TCP/IP协议的应用程序通常采用应用编程接口:UNIX BSD的套接字(socket)和UNIX System V的TLI(已经被淘汰),来实现网络进程之间的通信。

就目前而言,几乎所有的应用程序都是采用socket,而现在又是网络时代,网络中进程通信是无处不在,这就是我为什么说―一切皆s ocket‖。

TCP/IP(Transmission Control Protocol/Internet Protocol)即传输控制协议/网间协议,是一个工业标准的协议集,它是为广域网(WANs)设计的。

Linux下的CSocket编程--server端的简单示例

Linux下的CSocket编程--server端的简单示例

Linux下的CSocket编程--server端的简单⽰例Linux下的C Socket编程(三)server端的简单⽰例经过前⾯的client端的学习,我们已经知道了如何创建socket,所以接下来就是去绑定他到具体的⼀个端⼝上⾯去。

绑定socket到⼀个端⼝上bind()函数可以将socket绑定到⼀个端⼝上,client可以通过向这个端⼝发起请求,端⼝对应的socket便会与client端的socket连接。

#include<stdio.h>#include<stdlib.h>#include<sys/types.h>#include<sys/socket.h>#include<arpa/inet.h>int main() {int socket_desc;struct sockaddr_in server;socket_desc = socket(AF_INET, SOCK_STREAM, 0);if (-1 == socket_desc) {perror("cannot create socket");exit(1);}// 监听服务器⾃⾝server.sin_addr.s_addr = INADDR_ANY;server.sin_family = AF_INET;server.sin_port = htons(8888);// 绑定到端⼝if (bind(socket_desc, (struct sockaddr *)&server, sizeof(server)) < 0) {perror("cannot bind error");exit(1);}printf("bind success");close(socket_desc);return 0;}对于server.sin_addr.s_addr的更多信息可以参考通过将socket绑定到⼀个确定的端⼝上,我们接下来要做的便是接收这个端⼝下的所有数据。

linux、glibc中socket系统调用实现

linux、glibc中socket系统调用实现

/* %eax is < 0 if there was an error. */ cmpl $-125, %eax jae SYSCALL_ERROR_LABEL
/* Successful; return the syscall's value. */ L(pseudo_end):
ret ……
代码# define __socket socket 将__socket 定义为 socket,因此 ENTRY (__socket)即为 ENTRY (socket) 在这段汇编代码中,我们在 eax 保存当前系统调用号(这里是 socketcall),查看 SYS_ify 的定义,在 glibc/sysdeps/unix/sysv/linux/i386/sysdep.h 中:
#ifndef _SYS_SOCKETCALL_H #define _SYS_SOCKETCALL_H 1
/* Define unique numbers for the operations permitted on socket. Linux uses a single system call for all these functions. The relevant code file is /usr/include/linux/net.h. We cannot use a enum here because the values are used in assembler code. */
movl $SYS_ify(socketcall), %eax /* System call number in %eax. */
/* Use ## so `socket' is a separate token that might be #define'd. */

Linux下C语言的socket函数解析

Linux下C语言的socket函数解析

Linux下C语言的socket函数解析socketsocket()我们使用系统调用socket()来获得文件描述符:#include#includeint socket(int domain,int type,int protocol);第一个参数domain设置为“AF_INET”。

第二个参数是套接口的类型:SOCK_STREAM或SOCK_DGRAM。

第三个参数设置为0。

系统调用socket()只返回一个套接口描述符,如果出错,则返回-1。

bind()一旦你有了一个套接口以后,下一步就是把套接口绑定到本地计算机的某一个端口上。

但如果你只想使用connect()则无此必要。

下面是系统调用bind()的使用方法:#include#includeintbind(int sockfd,struct sockaddr*my_addr,int addrlen);第一个参数sockfd是由socket()调用返回的套接口文件描述符。

第二个参数my_addr是指向数据结构sockaddr的指针。

数据结构sockaddr中包括了关于你的地址、端口和IP地址的信息。

第三个参数addrlen可以设置成sizeof(structsockaddr)。

下面是一个例子:#include#include#include#define MYPORT 3490main(){int sockfd;struct sockaddr_inmy_addr;sockfd=socket(AF_INET,SOCK_STREAM,0);/*do someerror checking!*/my_addr.sin_family=AF_INET;/*hostbyteorder*/my_addr.sin_port=htons(MYPORT);/*short,network byte order*/my_addr.sin_addr.s_addr=inet_addr("132.241.5.10");bzero(&(my_addr.sin_zero),8);/*zero the rest of the struct*//*don't forget your error checking for bind():*/bind(sockfd,(struct sockaddr*)&my_addr,sizeof(struct sockaddr));...如果出错,bind()也返回-1。

linux socket 内核原理

linux socket 内核原理

Linux中的Socket是一种用于网络通信的编程接口,它允许进程通过网络进行数据传输。

Socket在Linux内核中的实现涉及到多个组件和原理。

1. 网络协议栈:Linux内核中的网络协议栈负责处理网络通信的各个层次,包括物理层、数据链路层、网络层和传输层。

Socket通过网络协议栈与网络进行交互。

2. 套接字数据结构:在Linux内核中,套接字(Socket)被实现为一种数据结构,用于表示网络连接。

套接字数据结构包含了连接的相关信息,如IP地址、端口号等。

3. 文件描述符:在Linux中,套接字被视为一种文件,因此每个套接字都有一个对应的文件描述符。

通过文件描述符,进程可以对套接字进行读写操作。

4. 网络设备驱动程序:Linux内核中的网络设备驱动程序负责处理网络设备的底层操作,如发送和接收数据包。

套接字通过网络设备驱动程序与网络设备进行通信。

5. 网络协议处理:当进程通过套接字发送或接收数据时,Linux内核会根据套接字的协议类型(如TCP或UDP)进行相应的协议处理。

这包括建立连接、数据分片、错误检测等操作。

6. 系统调用:在用户空间中,进程通过系统调用(如socket、bind、connect等)来创建和操作套接字。

系统调用会触发内核中相应的函数,完成套接字的创建和操作。

总的来说,Linux内核中的Socket实现涉及到网络协议栈、套接字数据结构、文件描述符、网络设备驱动程序、网络协议处理和系统调用等多个组件和原理。

这些组件和原理共同工作,使得进程能够通过套接字进行网络通信。

{"code":0,"msg":"请求出现异常","data":{}}。

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

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

福建电脑2012年第12期基于Linux的Socket网络编程及性能优化马丽洁(内蒙古电子信息职业技术学院内蒙古呼和浩特010070)【摘要】:本文主要从Socket的建立、配置、连接、数据传输和结束通信五个方面阐述了基于Linux的Socket网络编程的方法和步骤,最后又从最小化报文传输延迟、最小化系统调用负载、为Bandwidth Delay Product调节tcp窗口、动态优化GNU/linux TCP/IP协议栈四个方面进行性能优化,以使应用程序高效、稳定。

【关键词】:Linux,Socket,网络编程,性能优化Socket的英文原义是“孔”或“插座”,通常也称作"套接字",用于描述IP地址和端口,是一个通信链的句柄。

在Internet上的主机一般运行了多个服务软件,同时提供几种服务。

每种服务都打开一个Socket,并绑定到一个端口上,不同的端口对应于不同的服务。

Socket正如其英文原意那样,象一个多孔插座。

一台主机犹如布满各种插座的房间,每个插座有一个编号,有的插座提供220伏交流电,有的提供110伏交流电,有的则提供有线电视节目。

客户软件将插头插到不同编号的插座,就可以得到不同的服务。

socket也是一种文件描述符。

1.Socket编程1.1Socket的建立为了建立Socket,程式能够调用Socket函数,该函数返回一个类似于文档描述符的句柄。

Socket描述符是个指向内部数据结构的指针,他指向描述符表入口。

调用Socket函数时,socket执行体将建立一个Socket,实际上"建立一个Socket"意味着为一个Socket数据结构分配存储空间。

Socket执行体为您管理描述符表。

两个网络程式之间的一个网络连接包括五种信息:通信协议、本地协议地址、本地主机端口、远端主机地址和远端协议端口。

Socket数据结构中包含这五种信息。

1.2Socket的配置通过socket调用返回一个socket描述符后,在使用socket进行网络传输以前,必须配置该socket。

LinuxCSocket编程发送结构体、文件详解及实例

LinuxCSocket编程发送结构体、文件详解及实例

LinuxCSocket编程发送结构体、⽂件详解及实例利⽤Socket发送⽂件、结构体、数字等,是在Socket编程中经常需要⽤到的。

由于Socket只能发送字符串,所以可以使⽤发送字符串的⽅式发送⽂件、结构体、数字等等。

本⽂:1.memcpy Copy block of memory。

内存块拷贝函数,该函数是标准库函数,可以进⾏⼆进制拷贝数据。

函数原型: void * memcpy ( void * destination, const void * source, size_t num ); 函数说明:从source指向的地址开始拷贝num个字节到以destination开始的地址。

其中destination与source指向的数据类型⽆关。

2.Socket传输 使⽤memcpy将⽂件、结构体、数字等,可以转换为char数组,之后进⾏传输,接收⽅在使⽤memcpy将char数组转换为相应的数据。

下⾯的程序使⽤Socket传输结构体数据,由客户端传输给服务器端。

传输的结构体为:typedef struct{int ab;int num[1000000];}Node;服务器代码:1 #include<netinet/in.h>2 #include<sys/types.h>3 #include<sys/socket.h>4 #include<stdio.h>5 #include<stdlib.h>6 #include<string.h>78#define HELLO_WORLD_SERVER_PORT 66669#define LENGTH_OF_LISTEN_QUEUE 2010#define BUFFER_SIZE 10241112 typedef struct13 {14int ab;15int num[1000000];16 }Node;1718int main(int argc, char **argv)19 {20// set socket's address information21struct sockaddr_in server_addr;22 bzero(&server_addr, sizeof(server_addr));23 server_addr.sin_family = AF_INET;24 server_addr.sin_addr.s_addr = htons(INADDR_ANY);25 server_addr.sin_port = htons(HELLO_WORLD_SERVER_PORT);2627// create a stream socket28int server_socket = socket(PF_INET, SOCK_STREAM, 0);29if (server_socket < 0)30 {31 printf("Create Socket Failed!\n");32 exit(1);33 }3435//bind36if (bind(server_socket, (struct sockaddr*)&server_addr, sizeof(server_addr)))37 {38 printf("Server Bind Port: %d Failed!\n", HELLO_WORLD_SERVER_PORT);39 exit(1);40 }4142// listen43if (listen(server_socket, LENGTH_OF_LISTEN_QUEUE))45 printf("Server Listen Failed!\n");46 exit(1);47 }4849while(1)50 {51struct sockaddr_in client_addr;52 socklen_t length = sizeof(client_addr);5354int new_server_socket = accept(server_socket, (struct sockaddr*)&client_addr, &length);55if (new_server_socket < 0)56 {57 printf("Server Accept Failed!\n");58break;59 }6061 Node *myNode=(Node*)malloc(sizeof(Node));6263int needRecv=sizeof(Node);64char *buffer=(char*)malloc(needRecv);65int pos=0;66int len;67while(pos < needRecv)68 {69 len = recv(new_server_socket, buffer+pos, BUFFER_SIZE, 0);70if (len < 0)71 {72 printf("Server Recieve Data Failed!\n");73break;74 }75 pos+=len;7677 }78 close(new_server_socket);79 memcpy(myNode,buffer,needRecv);80 printf("recv over ab=%d num[0]=%d num[999999]=%d\n",myNode->ab,myNode->num[0],myNode->num[999999]);81 free(buffer);82 free(myNode);83 }84 close(server_socket);8586return0;87 }View Code客户端代码:1 #include <sys/types.h>2 #include <sys/socket.h> // 包含套接字函数库3 #include <stdio.h>4 #include <netinet/in.h> // 包含AF_INET相关结构5 #include <arpa/inet.h> // 包含AF_INET相关操作的函数6 #include <unistd.h>7 #include <string.h>8 #include <stdlib.h>9 #include <fcntl.h>10 #include <sys/shm.h>11 #include <pthread.h>1213#define MYPORT 666614#define BUFFER_SIZE 10241516 typedef struct17 {18int ab;19int num[1000000];20 }Node;2122int main()23 {24///sockfd25int sock_cli = socket(AF_INET,SOCK_STREAM, 0);2627struct sockaddr_in servaddr;28 memset(&servaddr, 0, sizeof(servaddr));29 servaddr.sin_family = AF_INET;30 servaddr.sin_port = htons(MYPORT);31 servaddr.sin_addr.s_addr = inet_addr("127.0.0.1");3233if (connect(sock_cli, (struct sockaddr *)&servaddr, sizeof(servaddr)) < 0)35 perror("connect");36 exit(1);37 }3839 Node *myNode=(Node*)malloc(sizeof(Node));40 myNode->ab=123;41 myNode->num[0]=110;42 myNode->num[999999]=99;4344int needSend=sizeof(Node);45char *buffer=(char*)malloc(needSend);46 memcpy(buffer,myNode,needSend);4748int pos=0;49int len=0;50while(pos < needSend)51 {52 len=send(sock_cli, buffer+pos, BUFFER_SIZE,0); 53if(len <= 0)54 {55 perror("ERRPR");56break;57 }58 pos+=len;59 }60 free(buffer);61 free(myNode);62 close(sock_cli);63 printf("Send over!!!\n");64return0;65 }View Code服务器端执⾏输出:。

常用socket函数详解

常用socket函数详解

常⽤socket函数详解常⽤socket函数详解关于socket函数,每个的意义和基本功能都知道,但每次使⽤都会去百度,参数到底是什么,返回值代表什么意义,就是说⽤的少,也记得不够精确。

每次都查半天,经常烦恼于此。

索性都弄得清楚、通透,并记录下来,⼀来便于⾃⼰记忆,再者以防⽇后查阅、回顾。

主要介绍:socket、bind、listen、connect、accept、send、sendto、recv、recvfrom、close、shutdown⽹络中的进程是通过socket来通信的,那什么是socket呢?socket起源于Unix,⽽Unix/Linux基本哲学之⼀就是“⼀切皆⽂件”,都可以⽤“打开open –> 读写write/read –> 关闭close”模式来操作。

我的理解就是Socket就是该模式的⼀个实现,socket即是⼀种特殊的⽂件。

其在linux和windows环境下的头⽂件主要是:#include<sys/socket.h>和#include<WinSock2.h>下⾯较为详细的介绍各个函数的使⽤⽅法,及返回值判断和处理。

另外,若想对函数调⽤后内核的详细动作过程,可参考UNIX⽹络编程第⼀卷或TCPIP详解第⼆卷。

1.socketint socket(int domain,int type, int protocol)_________________________返回值:⾮负描述符 – 成功,-1 - 出错其中:family指明了协议族/域,通常AF_INET、AF_INET6、AF_LOCAL等;type是套接⼝类型,主要SOCK_STREAM、SOCK_DGRAM、SOCK_RAW;protocol⼀般取为0。

成功时,返回⼀个⼩的⾮负整数值,与⽂件描述符类似。

对于windows环境下,在调⽤该函数之前需⾸先调⽤WSAStartup函数完成对Winsock服务的初始化,如#include<WinSock2.h>WSADATA wdata;if ( WSAStartup(MAKEWORD(2,2), &wdata) !=0 ){return INVALID_SOCKET;}后⾯即可调⽤socket函数,参数意义与linux环境⼀致。

Linux下基于TCP的预先派生子进程服务器的Socket编程

Linux下基于TCP的预先派生子进程服务器的Socket编程

No3 .
电 子 设 计 工 程
Elc r n c De in E g n e i g e to i sg n i e r n
2 1 年 2月 01
Fb 2 1 e . 01
Ln x下基 于 T P的预 iu C 先派 生子进程 服务器 的
务 器 能 够及 时 处 理 新 的 客 户连 接 . 响 应 时 间减 小到 并 发 服 务 器 的 三 分之 一 , 到 了 对服 务 器性 能优 化 的 目的 。 且 达
关 键 词 : o k t T P 预 先 派 生 子 进 程 :多进 程 S ce: C : 中图 分 类 号 : P 9 . T 3 30 9 文献标识码 : A 文 章 编 号 :1 7 — 2 6 2 1 ) 3 0 4 — 4 6 4 6 3 (0 10 — 13 0
sre n r- r igs re. in n ev rpo rmsrno C i iu ep ciey T ersl s o dta nte ev ra dp ef kn e r Cl t ds re rga a n P Sw t Ln xrs e t l. h e u ̄ h we h ti h o v e a h v
tesre' p r r n e h e r e o ma c . v s f Ke r s o k t C y wo d :S c e ;T P;p eo k n ;mu t p o e s r fr i g l — r c s i
Sce o k t编 程
和 家强 .刘彦 隆
( 原 理 工 大 学 信 息 工 程 学 院 ,山 西 太 原 0 0 2 ) 太 30 4 摘 要 : 述 了客 户I . 器 模 型 以及 常 见 的服 务 器 类 型— — 基 于 T P的 并 发 服 务 器 。在 一 个基 于 T P 回射 服 务 器 描 J务 l  ̄ C C 程 序 的基 础 上 . 合 实 际 We 结 b应 用 中的 多 进 程 服 务 器模 型 , 虑 到 原 有 的 客 户/ . 器 交 互 存 在 的 问 题 , 进 了客 考 J务 l  ̄ 改 户程 序 . 计 了 实现 并 发 功 能 的 客 户 程 序 、 设 并发 服 务 器 以 及 预 先 派 生 子 进 程 服 务 器 。在 装 有 Ln X的 P iU C上 分 别 进 行 客 户程 序 和服 务 器 程 序 的 测 试 。 实验 结 果 表 明 : 与 并 发 客 户 的 T P交 互 中 , 在 C 与并 发 服 务 器相 比 , 先 派 生 子 进 程 服 预

linux创建socket收发链路层报文的c语言代码

linux创建socket收发链路层报文的c语言代码

linux创建socket收发链路层报文的c语言代码引言概述:在Linux操作系统中,使用C语言编写代码可以创建socket并进行收发链路层报文的操作。

本文将详细介绍如何使用C语言编写代码来实现这一功能。

正文内容:1. socket的创建1.1. 引入必要的头文件:在C语言代码中,需要引入一些必要的头文件,如<sys/types.h>、<sys/socket.h>和<netinet/in.h>等,以便使用相关的函数和数据结构。

1.2. 创建socket:使用socket()函数可以创建一个socket,该函数需要指定协议族、套接字类型和协议类型等参数。

常用的协议族有AF_PACKET(链路层协议族)、AF_INET(IPv4协议族)和AF_INET6(IPv6协议族)等。

1.3. 设置socket选项:可以使用setsockopt()函数来设置socket的选项,如设置接收和发送缓冲区的大小等。

2. 绑定socket2.1. 创建一个用于绑定的结构体:使用struct sockaddr_ll结构体来保存链路层地址信息,包括接口索引、协议类型和目标MAC地址等。

2.2. 绑定socket:使用bind()函数将socket与特定的链路层地址绑定,以便接收和发送链路层报文。

3. 发送链路层报文3.1. 构建报文:使用C语言的数据结构和函数来构建链路层报文,包括设置目标MAC地址、源MAC地址、协议类型和数据等。

3.2. 发送报文:使用sendto()函数发送链路层报文,该函数需要指定socket、报文数据和报文长度等参数。

4. 接收链路层报文4.1. 创建一个接收缓冲区:使用malloc()函数动态分配一个足够大的缓冲区来接收链路层报文。

4.2. 接收报文:使用recvfrom()函数接收链路层报文,该函数需要指定socket、接收缓冲区和缓冲区大小等参数。

5. 关闭socket5.1. 关闭socket:使用close()函数关闭已创建的socket,释放相关资源。

Linux C 一些函数 所属的头文件

Linux C 一些函数 所属的头文件

Linux C 一些函数所属的头文件在编写程序时,有时总是不记得所使用的函数在哪个库函数中。

现在先把自己以前经常用到的函数头文件总结一下。

有不对的地方还请指教。

1,系统调用文件的操作函数#inlclude <fcntl.h>int open(char *name,int how) 第二个参数,O_RDONLY O_WRONL Y O_RDWR O_CREAT #include <unistd.h>int close(int fd)size_t read(int fd,void *buf, size_t count)size_t write(int fd,const void *buf,size_t count)sleep(1) 系统睡眠一秒钟,最小单位为一秒。

#define msleep(x) usleep(x*1000)msleep(500); 系统睡眠0.5秒#include <stdio.h>perror("会出现错误的函数名")#include <string.h>char *strerror(int errnum) 依据错误代码errnum来查找错误原因字符串char *strcpy(char *dest,const char *src)int strcmp(char *s1,const char *s2) s1若等于s2的值则返回0值int strncmp(char *s1,const char *s2,int n) 前n个字符串比较2,进程控制函数#include <unistd.h>pid_t fork(void) 子进程中返回0 父进程中返回子进程ID 出错返回-1pid_t getpid(void) pid_t getppid(void)pid_t vfork(void)exec函数族进程pid 的类型为pid_t 类型,它包含于#include <sys/types.h> 若定义一个进程pid变量,则需要包含此头文件exit(n)结束进程父进程可以由wait函数来获得子进程结束装状态。

SOCKET网络编程:Linux下实现聊天室

SOCKET网络编程:Linux下实现聊天室

SOCKET网络编程:Linux下实现聊天室程序介绍:本聊天室程序在Ubuntu下,采用C语言实现,结构为Client/Server结构;服务端程序通过共享存储区存储聊天数据,并发送给每个连接的客户端;服务端程序和客户端程序都是通过父子进程分别负责发送和接收数据的,以避免数据冲撞;需按以下格式调用客户端程序:client.exe 服务端主机IP 端口号(本程序设定为:3490) 用户名(在聊天室中显示的用户名)。

程序截图://--------------------------------服务端----------------------------------------------//--------------------------------客户端1:真水无香--------------------------------------//--------------------------------客户端2:蜡笔小新--------------------------------------程序代码如下://--------------------------------server.c-------------------------------------------------- //包含工程所需的头文件#include<stdio.h>#include<stdlib.h>#include<sys/types.h>//数据类型定义#include<sys/stat.h>#include<netinet/in.h>//定义数据结构sockaddr_in#include<sys/socket.h>//提供socket函数及数据结构#include<string.h>#include<unistd.h>#include<signal.h>#include<sys/ipc.h>#include<errno.h>#include<sys/shm.h>#include<time.h>#define PERM S_IRUSR|S_IWUSR#define MYPORT 3490 //宏定义定义通信端口#define BACKLOG 10 //宏定义,定义服务程序可以连接的最大客户数量#define WELCOME "|----------Welcome to the chat room! ----------|"//宏定义,当客户端连接服务端时,想客户发送此欢迎字符串//转换函数,将int类型转换成char *类型void itoa(int i,char*string){int power,j;j=i;for(power=1;j>=10;j/=10)power*=10;for(;power>0;power/=10){*string++='0'+i/power;i%=power;}*string='\0';}//得到当前系统时间void get_cur_time(char * time_str){time_t timep;struct tm *p_curtime;char *time_tmp;time_tmp=(char *)malloc(2);memset(time_tmp,0,2);memset(time_str,0,20);time(&timep);p_curtime = localtime(&timep);strcat(time_str," (");itoa(p_curtime->tm_hour,time_tmp);strcat(time_str,time_tmp);strcat(time_str,":");itoa(p_curtime->tm_min,time_tmp);strcat(time_str,time_tmp);strcat(time_str,":");itoa(p_curtime->tm_sec,time_tmp);strcat(time_str,time_tmp);strcat(time_str,")");free(time_tmp);}//创建共享存储区key_t shm_create(){key_t shmid;//shmid = shmget(IPC_PRIVATE,1024,PERM);if((shmid = shmget(IPC_PRIVATE,1024,PERM)) == -1){fprintf(stderr,"Create Share Memory Error:%s\n\a",strerror(errno)); exit(1);}return shmid;}//端口绑定函数,创建套接字,并绑定到指定端口int bindPort(unsigned short int port){int sockfd;struct sockaddr_in my_addr;sockfd = socket(AF_INET,SOCK_STREAM,0);//创建基于流套接字my_addr.sin_family = AF_INET;//IPv4协议族my_addr.sin_port = htons(port);//端口转换my_addr.sin_addr.s_addr = INADDR_ANY;bzero(&(my_addr.sin_zero),0);if(bind(sockfd,(struct sockaddr*)&my_addr,sizeof(struct sockaddr)) == -1){perror("bind");exit(1);}printf("bing success!\n");return sockfd;}int main(int argc, char *argv[]){int sockfd,clientfd,sin_size,recvbytes; //定义监听套接字、客户套接字pid_t pid,ppid; //定义父子线程标记变量char *buf, *r_addr, *w_addr, *temp, *time_str;//="\0"; //定义临时存储区struct sockaddr_in their_addr; //定义地址结构key_t shmid;shmid = shm_create(); //创建共享存储区temp = (char *)malloc(255);time_str=(char *)malloc(20);sockfd = bindPort(MYPORT);//绑定端口while(1){if(listen(sockfd,BACKLOG) == -1)//在指定端口上监听{perror("listen");exit(1);}printf("listening......\n");if((clientfd = accept(sockfd,(struct sockaddr*)&their_addr,&sin_size)) == -1)//接收客户端连接{perror("accept");exit(1);}printf("accept from:%d\n",inet_ntoa(their_addr.sin_addr));send(clientfd,WELCOME,strlen(WELCOME),0);//发送问候信息 buf = (char *)malloc(255);ppid = fork();//创建子进程if(ppid == 0){//printf("ppid=0\n");pid = fork(); //创建子进程while(1){if(pid > 0){//父进程用于接收信息memset(buf,0,255);//printf("recv\n");//sleep(1);if((recvbytes = recv(clientfd,buf,255,0)) <= 0) {perror("recv1");close(clientfd);raise(SIGKILL);exit(1);}//write buf's data to share memoryw_addr = shmat(shmid, 0, 0);memset(w_addr, '\0', 1024);strncpy(w_addr, buf, 1024);get_cur_time(time_str);strcat(buf,time_str);printf(" %s\n",buf);}else if(pid == 0){//子进程用于发送信息//scanf("%s",buf);sleep(1);r_addr = shmat(shmid, 0, 0);//printf("---%s\n",r_addr);//printf("cmp:%d\n",strcmp(temp,r_addr));if(strcmp(temp,r_addr) != 0){strcpy(temp,r_addr);get_cur_time(time_str);strcat(r_addr,time_str);//printf("discriptor:%d\n",clientfd);//if(send(clientfd,buf,strlen(buf),0) == -1)if(send(clientfd,r_addr,strlen(r_addr),0) == -1){perror("send");}memset(r_addr, '\0', 1024);strcpy(r_addr,temp);}}elseperror("fork");}}}printf("------------------------------\n");free(buf);close(sockfd);close(clientfd);return 0;}//-----------------------------client.c------------------------------------------------- //包含工程所需的头文件#include<stdio.h>#include<netinet/in.h>//定义数据结构sockaddr_in#include<sys/socket.h>//提供socket函数及数据结构#include<sys/types.h>//数据类型定义#include<string.h>#include<stdlib.h>#include<netdb.h>#include<unistd.h>#include<signal.h>#include<time.h>int main(int argc, char *argv[]){struct sockaddr_in clientaddr;//定义地址结构pid_t pid;int clientfd,sendbytes,recvbytes;//定义客户端套接字struct hostent *host;char *buf,*buf_r;if(argc < 4){printf("usage:\n");printf("%s host port name\n",argv[0]);exit(1);}host = gethostbyname(argv[1]);if((clientfd = socket(AF_INET,SOCK_STREAM,0)) == -1) //创建客户端套接字{perror("socket\n");exit(1);}//绑定客户端套接字clientaddr.sin_family = AF_INET;clientaddr.sin_port = htons((uint16_t)atoi(argv[2]));clientaddr.sin_addr = *((struct in_addr *)host->h_addr);bzero(&(clientaddr.sin_zero),0);if(connect(clientfd,(struct sockaddr *)&clientaddr,sizeof(struct sockaddr)) == -1) //连接服务端{perror("connect\n");exit(1);}buf=(char *)malloc(120);memset(buf,0,120);buf_r=(char *)malloc(100);if( recv(clientfd,buf,100,0) == -1){perror("recv:");exit(1);}printf("\n%s\n",buf);pid = fork();//创建子进程while(1){if(pid > 0){//父进程用于发送信息//get_cur_time(time_str);strcpy(buf,argv[3]);strcat(buf,":");memset(buf_r,0,100);//gets(buf_r);fgets(buf_r,100,stdin);strncat(buf,buf_r,strlen(buf_r)-1);//strcat(buf,time_str);//printf("---%s\n",buf);if((sendbytes = send(clientfd,buf,strlen(buf),0)) == -1) {perror("send\n");exit(1);}}else if(pid == 0){//子进程用于接收信息memset(buf,0,100);if(recv(clientfd,buf,100,0) <= 0){perror("recv:");close(clientfd);raise(SIGSTOP);exit(1);}printf("%s\n",buf);}elseperror("fork");}close(clientfd);return 0;}。

Linux进程间通信方式之socket使用实例

Linux进程间通信方式之socket使用实例

Linux进程间通信⽅式之socket使⽤实例套接字是⼀种通信机制,凭借这种机制,客户/服务器系统的开发⼯作既可以在本地单机上进⾏,也可以跨⽹络进⾏。

套接字的特性有三个属性确定,它们是:域(domain),类型(type),和协议(protocol)。

套接字还⽤地址作为它的名字。

地址的格式随域(⼜被称为协议族,protocol family)的不同⽽不同。

每个协议族⼜可以使⽤⼀个或多个地址族定义地址格式。

1.套接字的域域指定套接字通信中使⽤的⽹络介质。

最常见的套接字域是AF_INET,它是指Internet⽹络,许多Linux局域⽹使⽤的都是该⽹络,当然,因特⽹⾃⾝⽤的也是它。

其底层的协议——⽹际协议(IP)只有⼀个地址族,它使⽤⼀种特定的⽅式来指定⽹络中的计算机,即IP地址。

在计算机系统内部,端⼝通过分配⼀个唯⼀的16位的整数来表⽰,在系统外部,则需要通过IP地址和端⼝号的组合来确定。

2.套接字类型流套接字(在某些⽅⾯类似域标准的输⼊/输出流)提供的是⼀个有序,可靠,双向字节流的连接。

流套接字由类型SOCK_STREAM指定,它们是在AF_INET域中通过TCP/IP连接实现的。

他们也是AF_UNIX域中常见的套接字类型。

数据包套接字与流套接字相反,由类型SOCK_DGRAM指定的数据包套接字不建⽴和维持⼀个连接。

它对可以发送的数据包的长度有限制。

数据报作为⼀个单独的⽹络消息被传输,它可能会丢失,复制或乱序到达。

数据报套接字实在AF_INET域中通过UDP/IP连接实现,它提供的是⼀种⽆需的不可靠服务。

3.套接字协议只要底层的传输机制允许不⽌⼀个协议来提供要求的套接字类型,我们就可以为套接字选择⼀个特定的协议。

先上⼀个代码服务端://s_unix.c#include <stdio.h>#include <sys/types.h>#include <sys/socket.h>#include <sys/un.h>#define UNIX_DOMAIN "/tmp/UNIX.domain"int main(void){socklen_t clt_addr_len;int listen_fd;int com_fd;int ret;int i;static char recv_buf[1024];int len;struct sockaddr_un clt_addr;struct sockaddr_un srv_addr;listen_fd=socket(PF_UNIX,SOCK_STREAM,0);if(listen_fd<0){perror("cannot create communication socket");return 1;}//set server addr_paramsrv_addr.sun_family=AF_UNIX;strncpy(srv_addr.sun_path,UNIX_DOMAIN,sizeof(srv_addr.sun_path)-1);unlink(UNIX_DOMAIN);//bind sockfd & addrret=bind(listen_fd,(struct sockaddr*)&srv_addr,sizeof(srv_addr));if(ret==-1){perror("cannot bind server socket");close(listen_fd);unlink(UNIX_DOMAIN);return 1;}//listen sockfdret=listen(listen_fd,1);if(ret==-1){perror("cannot listen the client connect request");close(listen_fd);unlink(UNIX_DOMAIN);return 1;}//have connect request use acceptlen=sizeof(clt_addr);com_fd=accept(listen_fd,(struct sockaddr*)&clt_addr,&len);if(com_fd<0){perror("cannot accept client connect request");close(listen_fd);unlink(UNIX_DOMAIN);return 1;}//read and printf sent client infoprintf("/n=====info=====/n");for(i=0;i<4;i++){memset(recv_buf,0,1024);int num=read(com_fd,recv_buf,sizeof(recv_buf));printf("Message from client (%d)) :%s/n",num,recv_buf);}close(com_fd);close(listen_fd);unlink(UNIX_DOMAIN);return 0;}客户端://c_unix.c#include <stdio.h>#include <sys/types.h>#include <sys/socket.h>#include <sys/un.h>#define UNIX_DOMAIN "/tmp/UNIX.domain"int main(void){int connect_fd;int ret;char snd_buf[1024];int i;static struct sockaddr_un srv_addr;//creat unix socketconnect_fd=socket(PF_UNIX,SOCK_STREAM,0);if(connect_fd<0){perror("cannot create communication socket");return 1;}srv_addr.sun_family=AF_UNIX;strcpy(srv_addr.sun_path,UNIX_DOMAIN);//connect serverret=connect(connect_fd,(struct sockaddr*)&srv_addr,sizeof(srv_addr)); if(ret==-1){perror("cannot connect to the server");close(connect_fd);return 1;}memset(snd_buf,0,1024);strcpy(snd_buf,"message from client");//send info serverfor(i=0;i<4;i++)write(connect_fd,snd_buf,sizeof(snd_buf));close(connect_fd);return 0;}使⽤套接字除了可以实现⽹络间不同主机间的通信外,还可以实现同⼀主机的不同进程间的通信,且建⽴的通信是双向的通信。

Linux下C和C++常用头文件

Linux下C和C++常用头文件

Linux下C和C++常用头文件linux下编程常用头文件一览========================================= <assert.h>验证程序断言<cpio.h>cpio归档值<ctype.h>字符类型<dirent.h>目录项<errno.h>出错码<fcntl.h>文件控制<float.h>浮点常数<signal.h>信号<stdarg.h>可变参数表<stddef.h>标准定义<stdio.h>标准I/O库<stdlib.h>公用函数<string.h>字符串操作<tar.h> tar归档值<termios.h>终端I/O<time.h>时间和日期<ulimit.h>用户限制<unistd.h>符号常数<utime.h>文件时间<sys/ipc.h> IPC<sys/msg.h>消息队列<sys/sem.h>信号量<sys/shm.h>共享存储<sys/stat.h>文件状态<sys/times.h>进程时间<sys/types.h>原系统数据类型<sys/wait.h>进程控制C/C++头文件一览========================================= ========================================= ===========C、传统C++#include <assert.h>//设定插入点#include <ctype.h>//字符处理#include <errno.h>//定义错误码#include <float.h>//浮点数处理#include <fstream.h>//文件输入/输出#include <iomanip.h>//参数化输入/输出#include <iostream.h>//数据流输入/输出#include <limits.h>//定义各种数据类型最值常量#include <locale.h>//定义本地化函数#include <math.h>//定义数学函数#include <stdio.h>//定义输入/输出函数#include <stdlib.h>//定义杂项函数及内存分配函数#include <string.h>//字符串处理#include <strstrea.h>//基于数组的输入/输出#include <time.h>//定义关于时间的函数#include <wchar.h>//宽字符处理及输入/输出#include <wctype.h>//宽字符分类========================================= 标准C++(同上的不再注释)#include <algorithm>//STL 通用算法#include <bitset>//STL 位集容器#include <cctype> //字符处理#include <cerrno> //定义错误码#include <clocale> //定义本地化函数#include <cmath> //定义数学函数#include <complex>//复数类#include <cstdio> //标准I/O库#include <cstdlib> //定义杂项函数及内存分配函数#include <cstring> //字符串处理#include <ctime> //定义关于时间的函数#include <deque>//STL 双端队列容器#include <exception>//异常处理类#include <fstream> //文件输入/输出#include <functional>//STL 定义运算函数(代替运算符)#include <limits>#include <list>//STL 线性列表容器#include <map>//STL 映射容器#include <iomanip>#include <ios>//基本输入/输出支持#include <iosfwd>//输入/输出系统使用的前置声明#include <iostream> //数据流输入/输出#include <istream>//基本输入流#include <ostream>//基本输出流#include <queue>//STL 队列容器#include <set>//STL 集合容器#include <sstream>//基于字符串的流#include <stack>//STL 堆栈容器#include <stdexcept>//标准异常类#include <streambuf>//底层输入/输出支持#include <string>//字符串类#include <utility>//STL 通用模板类#include <vector>//STL 动态数组容器#include <cwchar>#include <cwctype>======================================== C99 增加#include <complex.h>//复数处理#include <fenv.h>//浮点环境#include <inttypes.h>//整数格式转换#include <stdbool.h>//布尔环境#include <stdint.h>//整型环境#include <tgmath.h>//通用类型数学宏========================================= socket编程时常要用到:sys/types.h:数据类型定义sys/socket.h:提供socket函数及数据结构netinet/in.h:定义数据结构sockaddr_in arpa/inet.h:提供IP地址转换函数netdb.h:提供设置及获取域名的函数sys/ioctl.h:提供对I/O控制的函数sys/poll.h:提供socket等待测试机制的函数其他在网络程序中常见的头文件unistd.h:提供通用的文件、目录、程序及进程操作的函数errno.h:提供错误号errno的定义,用于错误处理fcntl.h:提供对文件控制的函数time.h:提供有关时间的函数crypt.h:提供使用DES加密算法的加密函数pwd.h:提供对/etc/passwd文件访问的函数shadow.h:提供对/etc/shadow文件访问的函数pthread.h:提供多线程操作的函数signal.h:提供对信号操作的函数sys/wait.h、sys/ipc.h、sys/shm.h:提供进程等待、进程间通讯(IPC)及共享内存的函数。

Window和Linux下Socket的区别

Window和Linux下Socket的区别

Window和Linux下Socket的区别1)头文件windows下winsock.h或winsock2.hlinux下netinet/in.h(大部分都在这儿),unistd.h(close函数在这儿),sys/socket.h(在in.h里已经包含了,可以省了),错误处理:errno.h2)初始化windows下需要用WSAStartup启动Ws2_32.lib,并且要用#pragma comment(lib,"Ws2_32")来告知编译器链接该lib。

linux下不需要WSADATA wsaData;err = WSAStartup(0x202,&wsaData);if ( err != 0 ){return 0;}else if ( LOBYTE( wsaData.wVersion ) != 2 || HIBYTE( wsaData.wVersion ) != 2 ) //检测是否支持这个版本{WSACleanup( );return 0;对应的退出清理用WSACleanup( );3)关闭socketwindows下closesocket(...)linux下close(...)4)类型windows下SOCKETlinux下int(我喜欢用long,这样保证是4byte,因为-1我总喜欢写成0xFFFF)5)获取错误码windows下getlasterror()/WSAGetLastError(),linux下,未能成功执行的socket操作会返回-1;如果包含了errno.h,就会设置errno变量extern int errno;int geterror(){return errno;}6)设置非阻塞windows下ioctlsocket() linux下fcntl(),需要头文件fcntl.hwindows下ioctlsocket(server_socket,FIONBIO,&ul); int ul = 1linux下fcntl(server_socket,F_SETFL, O_NONBLOCK); 包含头文件<fcntl.h>7)send函数最后一个参数windows下一般设置为0linux下最好设置为MSG_NOSIGNAL,如果不设置,在发送出错后有可能会导致程序退出linux下必须是后几个参数用到的socket中,值最大的数(整型)加1(另一种说法是设置为MSG_NOSIGNAL)8)毫秒级时间获取windows下GetTickCount()linux下gettimeofday()9)编译连接windows下ws2_32.liblinux下连接是使用参数:-lstdc运行时需要libstdc++.so.5,可在/usr/lib目录中创建一个链接。

Linux下Socket编程的端口问题(Address+already+in+use)

Linux下Socket编程的端口问题(Address+already+in+use)

Linux下Socket编程的端口问题( Bind(): Address already in use )转载请注明 原文: /xl_xunzhao/archive/2008/10/23/3130037.aspx最近在开发一个Linux下的聊天软件,每次修改了源代码并再次编译运行时,常遇到下面的地使用错误:Cann't bind server socket !: Address already in use虽然用Ctrl+C强制结束了进程,但错误依然存在,用netstat -an |grep 5120和ps aux |grep 5120都还能看到刚才用Ctrl+C“强制结束”了的进程,端口还是使用中,只好每次用kill结束进程,很是麻烦。

昨天晚上无意间浏览到IBM网站上的一篇题为《 Linux 个隐患》的文章,恍然大悟,今天试了一下,果然解决问题,在此表示套接字编程中的 5感谢,也希望更多的coder看到这篇文章,避免出错。

主要代码为:现在我每次用Ctrl+C强制结束进程后,用netstat和ps都还能看到端口在使用中,但运行程序不会出现“Address already in use”的错误了,实现了端口的重用。

以下是原文中的第三个隐患--地址使用错误地址使用错误(EADDRINUSE)您可以使用 bind API 函数来绑定一个地址(一个接口和一个端口)到一个套接字端点。

可以在服务器设置中使用这个函数,以便限制可能有连接到来的接口。

也可以在客户端设置中使用这个函数,以便限制应当供出去的连接所使用的接口。

bind 最常见的用法是关联端口号和服务器,并使用通配符地址(INADDR_ANY),它允许任何接口为到来的连接所使用。

bind 普遍遭遇的问题是试图绑定一个已经在使用的端口。

该陷阱是也许没有活动的套接字存在,但仍然禁止绑定端口(bind 返回 EADDRINUSE),它由 TCP 套接字状态TIME_WAIT 引起。

linuxsock_raw原始套接字编程

linuxsock_raw原始套接字编程

linux sock_raw原始套接字编程sock_raw原始套接字编程能够接收到本机网卡上的数据帧或数据包,对与监听网络的流量和分析是很有作用的.一共能够有3种方式创建这种socket1.socket(AF_INET, SOCK_RAW, IPPROTO_TCP|IPPROTO_UDP|IPPROTO_ICMP)发送接收ip数据包2.socket(PF_PACKET, SOCK_RAW, htons(ETH_P_IP|ETH_P_ARP|ETH_P_ALL))发送接收以太网数据帧3.socket(AF_INET, SOCK_PACKET, htons(ETH_P_IP|ETH_P_ARP|ETH_P_ALL))过时了,不要用啊明白得一下SOCK_RAW的原理, 比如网卡收到了一个14+20+8+100+4 的udp的以太网数据帧.第一,网卡对该数据帧进行硬过滤(依照网卡的模式不同会有不同的动作,若是设置了promisc混杂模式的话,那么不做任何过滤直接交给下一层输入例程,不然非本机mac或广播mac会被直接抛弃).依照上面的例子,若是成功的话,会进入ip 输入例程.可是在进入ip输入例程之前,系统会检查系统中是不是有通过socket(AF_PACKET, SOCK_RAW, ..)创建的套接字.若是有的话而且协议相符,在那个例子中确实是需要ETH_P_IP或ETH_P_ALL类型.系统就给每一个如此的socket接收缓冲区发送一个数据帧拷贝.然后进入下一步.第二,进入了ip输入例程(ip层会对该数据包进行软过滤,确实是检查校验或抛弃非本机ip或广播ip的数据包等,具体要参考源代码),例子中确实是若是成功的话会进入udp输入例程.可是在交给udp输入例程之前,系统会检查系统中是不是有通过socket(AF_INET, SOCK_RAW, ..)创建的套接字.若是有的话而且协议相符,在那个例子中确实是需要IPPROTO_UDP类型.系统就给每一个如此的socket接收缓冲区发送一个数据帧拷贝.然后进入下一步.最后,进入udp输入例程 ...ps:若是校验和犯错的话,内核会直接抛弃该数据包的.而可不能拷贝给sock_raw 的套接字,因为校验和都犯错了,数据确信有问题的包括所有信息都没成心义了.进一步分析他们的能力.1. socket(AF_INET, SOCK_RAW, IPPROTO_UDP);能:该套接字能够接收协议类型为(tcp udp icmp等)发往本机的ip数据包,从上面看的确实是20+8+100.不能:不能收到非发往本地ip的数据包(ip软过滤会抛弃这些不是发往本机ip的数据包).不能:不能收到从本机发送出去的数据包.发送的话需要自己组织tcp udp icmp等头部.能够setsockopt来自己包装ip 头部这种套接字用来写个ping程序比较适合2. socket(PF_PACKET, SOCK_RAW, htons(x));那个套接字比较壮大,创建这种套接字能够监听网卡上的所有数据帧.从上面看确实是20+20+8+100.最后一个以太网crc从来都不算进来的,因为内核已经判定过了,对程序来讲没有任何意义了.能: 接收发往本地mac的数据帧能: 接收从本机发送出去的数据帧(第3个参数需要设置为ETH_P_ALL)能: 接收非发往本地mac的数据帧(网卡需要设置为promisc混杂模式)协议类型一共有四个ETH_P_IP 0x800 只接收发往本机mac的ip类型的数据帧ETH_P_ARP 0x806 只同意发往本机mac的arp类型的数据帧ETH_P_ARP 0x8035 只同意发往本机mac的rarp类型的数据帧ETH_P_ALL 0x3 接收发往本机mac的所有类型ip arp rarp的数据帧, 接收从本机发出的所有类型的数据帧.(混杂模式打开的情形下,会接收到非发往本地mac的数据帧)发送的时候需要自己组织整个以太网数据帧.所有相关的地址利用struct sockaddr_ll 而不是struct sockaddr_in(因为协议簇是PF_PACKET不是AF_INET了),比如发送给某个机械,对方的地址需要利用struct sockaddr_ll.这种socket大小通吃,强悍下面是一段相关的代码:perror("iotcl()");return -1;}return 0;}int unset_promisc(char *interface, int fd) {struct ifreq ifr;strcpy(ifr.ifr_name, interface);if(ioctl(fd, SIOCGIFFLAGS, &ifr) == -1) {perror("iotcl()");return -1;}ifr.ifr_flags &= ~IFF_PROMISC;if(ioctl(fd, SIOCSIFFLAGS, &ifr) == -1) {perror("iotcl()");return -1;}return 0;}3. socket(AF_INET, SOCK_PACKET, htons(ETH_P_ALL))那个最好不要用,终归我不用...总结利用方式: 1.只想收到发往本机某种协议的ip数据包的话用第一种就足够了2. 更多的详细的内容请利用第二种.包括ETH_P_ALL参数和混杂模式都能够使它的能力不断的增强.ps:很多自己的方式.虚拟机测试环境.有错欢迎指出交流qq:110024218我写的ping#include "arpa/inet.h"#include "signal.h"#include "sys/time.h"extern int errno;int sockfd;struct sockaddr_in addr; //peer addrchar straddr[128]; //peer addr ip(char*)char sendbuf[2048];char recvbuf[2048];int sendnum;int recvnum;int datalen = 30;unsigned short my_cksum(unsigned short *data, int len) {int result = 0;for(int i=0; i<len/2; i++) {result += *data;data++;}while(result >> 16)result = (result&0xffff) + (result>>16);return ~result;}void tv_sub(struct timeval* recvtime, const struct timeval* sendtime) { int sec = recvtime->tv_sec - sendtime->tv_sec;int usec = recvtime->tv_usec - sendtime->tv_usec;if(usec >= 0) {recvtime->tv_sec = sec;recvtime->tv_usec = usec;} else {recvtime->tv_sec = sec-1;recvtime->tv_usec = -usec;}}void send_icmp() {struct icmp* icmp = (struct icmp*)sendbuf;icmp->icmp_type = ICMP_ECHO;icmp->icmp_code = 0;icmp->icmp_cksum = 0;icmp->icmp_id = getpid(); //needn't use htons() call, because peer networking kernel didn't handle this data and won't make different meanings(bigdian litteldian)icmp->icmp_seq = ++sendnum; //needn't use hotns() call too.gettimeofday((struct timeval*)icmp->icmp_data, NULL);int len = 8+datalen;icmp->icmp_cksum = my_cksum((unsigned short*)icmp, len);int retval = sendto(sockfd, sendbuf, len, 0, (struct sockaddr*)&addr, sizeof(addr));if(retval == -1){perror("sendto()");exit(-1);} else {// printf("send icmp request to %s(%d) bytes\n", straddr, len);}}void recv_icmp() {struct timeval *sendtime;struct timeval recvtime;for(;;) {int n = recvfrom(sockfd, recvbuf, sizeof(recvbuf), 0, 0, 0);if(n == -1) {if(errno == EINTR)continue;else {perror("recvfrom()");exit(-1);}} else {gettimeofday(&recvtime, NULL);struct ip *ip = (struct ip*)recvbuf;if(ip->ip_src.s_addr != addr.sin_addr.s_addr) {// printf("ip_src is not : %s\n", straddr);continue;}struct icmp *icmp = (struct icmp*)(recvbuf + ((ip->ip_hl)<<2));if(icmp->icmp_id != getpid()) {// printf("icmp_id is not :%d\n", getpid());continue;}recvnum++;sendtime = (structtimeval*)icmp->icmp_data;tv_sub(&recvtime, sendtime);printf("imcp echo from %s(%dbytes)\tttl=%d\tseq=%d\ttime=%d.%06d s\n", straddr, n, ip->ip_ttl, icmp->icmp_seq, _sec, _usec);}}}void catch_sigalrm(int signum) {send_icmp();alarm(1);}void catch_sigint(int signum) {printf("\nPing statics:send %d packets, recv %d packets, %d%% lost...\n", sendnum, recvnum, (int)((float)(sendnum-recvnum)/sendnum)*100);exit(0);}int main(int argc, char **argv) {if(argc != 2) {printf("please use format: ping hostname\n");exit(-1);}sockfd = socket(AF_INET, SOCK_RAW, IPPROTO_ICMP);if(sockfd == -1) {perror("socket()");return -1;}/*int sendbufsize = 180;socklen_t sendbufsizelen = sizeof(sendbufsize);if(setsockopt(sockfd, SOL_SOCKET, SO_RCVBUF, &sendbufsize, sendbufsizelen) == -1)perror("setsockopt()");int recvbufsize;socklen_t recvbufsizelen;if(getsockopt(sockfd, SOL_SOCKET, SO_RCVBUF, &recvbufsize, &recvbufsizelen) == -1)perror("getsockopt()");*/memset(&addr, 0, sizeof(addr));addr.sin_family = AF_INET;int retval = inet_pton(AF_INET, argv[1], &addr.sin_addr);if(retval == -1 || retval == 0) {struct hostent* host = gethostbyname(argv[1]);if(host == NULL) {fprintf(stderr, "gethostbyname(%s):%s\n", argv[1], strerror(errno));exit(-1);}/*if(host->h_name != NULL)printf("hostent.h_name:%s\n", host->h_name);if(host->h_aliases != NULL && *(host->h_aliases) != NULL)printf("hostent.h_aliases:%s\n", *(host->h_aliases));printf("hostent.h_addrtype:%d\n",host->h_addrtype);printf("hostent.h_length:%d\n", host->h_length);*/if(host->h_addr_list != NULL && *(host->h_addr_list) != NULL) {strncpy((char*)&addr.sin_addr,*(host->h_addr_list), 4);inet_ntop(AF_INET, *(host->h_addr_list), straddr, sizeof(straddr));}printf("Ping address:%s(%s)\n\n", host->h_name, straddr);} else {strcpy(straddr, argv[1]);printf("Ping address:%s(%s)\n\n", straddr, straddr);}struct sigaction sa1;memset(&sa1, 0, sizeof(sa1));sa1.sa_handler = catch_sigalrm;sigemptyset(&sa1.sa_mask);sa1.sa_flags = 0;if(sigaction(SIGALRM, &sa1, NULL) == -1)perror("sigaction()");struct sigaction sa2;memset(&sa2, 0, sizeof(sa2));sa2.sa_handler = catch_sigint;sigemptyset(&sa2.sa_mask);sa2.sa_flags = 0;if(sigaction(SIGINT, &sa2, NULL) == -1)perror("sigaction()");。

Linux内核Socket CAN中文文档

Linux内核Socket CAN中文文档

Linux内核Socket CAN中文文档Linux内核Socket CAN中文文档分类:嵌入式内核驱动2012-06-08 20:36 3711人阅读评论(1) 收藏举报socketlinux内核网络structfilterlinux自己在年假中空闲之余翻译的内核中Socket CAN的文档,原文地址在:http://lxr.linux.no/linux+v2.6.34/Documentation/networking/ can.txt但是这篇文档没有涉及广播管理协议套接字(SOCK_DGRAM) 的内容。

另外一篇比较好的Socket CAN 的英文文档是(详细介绍了广播管理协议套接字):Low Level CAN Framework Application Programmers Interface/docs/socketcan/llcf-api.h tml#SECTION00051000000000000000自己暂时没时间翻译这篇文章了,有空再说吧。

自己英文水平有限,希望高人指正。

============================================ ==================================== 这篇文章主要针对can协议簇(aka socket can)这篇文章包含以下内容:===============1 概述--什么是Socket CAN?2 动机--为什么使用socket API接口?3 Socket CAN详解 3.1 接收队列 3.2 发送帧的本地回环 3.3 网络安全相关 3.4 网络故障监测4 如何使用Socket CAN 4.1 使用can_filter的原始套接字(RAW socket) 4.1.1 原始套接字选项CAN_RAW_FILTER 4.1.2 原始套接字选项CAN_RAW_ERR_FILTER 4.1.3 原始套接字选项CAN_RAW_LOOPBACK 4.1.4 原始套接字选项CAN_RAW_RECV_OWN_MSGS 4.2 广播管理协议套接字(SOCK_DGRAM) 4.3 面向连接的传输协议(SOCK_SEQPACKET) 4.4 无连接的传输协议(SOCK_DGRAM)5 Socket CAN核心模块 5.1 can.ko模块的参数5.2 procfs接口 5.3 写一个自己的CAN协议模块6 CAN网络驱动 6.1 常见设置 6.2 发送帧的本地回环 6.3 CAN控制器的硬件过滤 6.4 虚拟的CAN驱动(vcan) 6.5 CAN网络设备驱动接口6.5.1 Netlink接口--设置/获取设备属性 6.5.2 设置CAN的比特_时序 6.5.3 启动和停止CAN网络设备 6.6 支持Socket CAN的硬件7 学习Socket CAN的相关资源8 贡献者名单==============现在开始===================1. 概述--什么是Socket CAN?================== socketcan子系统是在Linux下CAN协议(Controller AreaNetwork)实现的一种实现方法。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

linux下socket编程常用头文件
sys/types.h:数据类型定义
sys/socket.h:提供socket函数及数据结构
netinet/in.h:定义数据结构sockaddr_in
arpa/inet.h:提供IP地址转换函数
netdb.h:提供设置及获取域名的函数
sys/ioctl.h:提供对I/O控制的函数
sys/poll.h:提供socket等待测试机制的函数
其他在网络程序中常见的头文件
unistd.h:提供通用的文件、目录、程序及进程操作的函数
errno.h:提供错误号errno的定义,用于错误处理
fcntl.h:提供对文件控制的函数 time.h:提供有关时间的函数
crypt.h:提供使用DES加密算法的加密函数
pwd.h:提供对/etc/passwd文件访问的函数
shadow.h:提供对/etc/shadow文件访问的函数
pthread.h:提供多线程操作的函数
signal.h:提供对信号操作的函数
sys/wait.h、sys/ipc.h、sys/shm.h:提供进程等待、进程间通讯(IPC)及共享内存的函数
建议:在编写网络程序时,可以直接使用下面这段头文件代码
#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netdb.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <errno.h>
#include <malloc.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <sys/ioctl.h>
#include <stdarg.h>
#include <fcntl.h>
#include <fcntl.h>
涉及到用户权限及密码验证问题时加入如下语句:
#include <shadow.h>
#include <crypt.h>
#include <pwd.h>
需要注意的是,应该在编译时链接加密算法库,即增加编译选项: -lcrypt
涉及到文件及时间操作加入如下语句:
#include <sys/time.h>
#include <utime.h>
#include <time.h>
#include <sys/stat.h>
#include <sys/file.h>
涉及到多进程操作时加入如下语句:
#include <sys/wait.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <signal.h>
涉及到多线程操作时加入如下语句:
#include <pthread.h>
#include <sys/poll.h>
需要注意的是,应该在编译时链接线程库,即增加编译选项:-lthread。

相关文档
最新文档