2018-11-10 18:17:00 genzld 阅读数 412

基础知识:

  首先我们来了解Linux网络API

  ①socket地址API: socket最开始的含义:一个IP地址和端口对(ip,port)。他唯一的表示了TCP通信的一端。
  ②socket基础API: socket主要的API包括创建socket,命名socket,监听socket,接受连接,发起连接,读写数据,获取地址信息,检测带外标记,以及读取和设置socket选项。
  ③网络信息API: 以实现主机名和IP地址之间的转换;服务名称和端口号之间的转换。这些API都定义在netdb.h头文件中。

 

主机字节序和网络字节序

1.字节序:现代CPU的累加器一次都能装载(至少)4字节(32位机),即一个整数,那么这4个字节在内存中排列的顺序将影响它被累加器转载成的整数值。这就是字节序问题。

大端字节序 一个整数的高位字储存在内存的低地址处。
小端字节序 是指整数的高位字节存储在内存的高地址。

 

主机字节序 现代PC大多采用小端字节序,因此成为主机字节序。
网络字节序 大端字节序也称为网络字节序。

Linux提供了4个函数来完成主机字节序列和网络字节序列的转换以保证接收端和发送端的一致性

#include<netinet/in.h>
unsigned long int htonl(unsigned long int hostlong);

unsigned short int htons(unsigned short int hostshort);

unsigned long int ntohl(unsigned long int netlong);

unsigned short int ntohs(unsigned short int netshort);
//他们的含义很明确,比如htonl表示为:“host to nettwork long”
//在这四个函数中,长整型函数通常用来转换IP地址,
//短整型函数用来转换端口号。


 

TCP函数了解:

系统调用函数1:创建socket(文件描述符)

函数头文件:

#include<sys/types.h>
#include<sys/socket.h>

函数原型:

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

函数参数解释:

①domain: 告诉系统使用哪个底层协议族。对于TCP协议族:PF_INET(Protocol Family of Internet,用于IPv4)或PF_INET6(IPv6);
②type:

指定服务类型---》流服务:SOCK_STREAM  和 数据报服务: SOCK_UGRAM。 对于TCP/IP协议族,采用流服务为其运输层采用TCP协议,采用数据报服务表明其运输层采用UDP协议。

③protocol: 在前两个参数构成的协议集合下,在选择一个具体的协议。(前两个参数已经决定了他的值),默认设置为0使用默认协议。

函数返回值:

socket系统调用成功时返回一个socket文件描述符,失败返回-1。

 

系统调用函数2:bind  命名socket

函数头文件:

#include<sys/types.h>
#include<sys/socket.h>

函数原型:

int bind(int sockfd , const struct sockaddr* my_addr,socklen_t addrlen);

函数解释:

创建socket时,我们给它指定了地址族,但是并未指定使用该地址族中的那个具体的socket地址,将一个socket和socket地址绑定称为给socket命名。在服务器程序中,我们通常要命名socket,这样客户端才能知道该如何连接它。而客户端通常不需要命名socket,而是采用匿名的socket地址。

函数参数:

①my_addr bind my_addr bind将my_addr所指的socket地址分配给未命名的sockfd文件描述符。
②addlen 指出该socket地址的长度。

函数返回值:

成功 返回0
失败 返回-1:失败通常有两种情况 EACCES:无权限访问该端口号 EADDRINUSE: 端口号被占用。

系统调用函数3:listen //监听socket

函数原型:

int listen(int sockfd,int backlog);

函数解释:

socket被命名之后还不能马上接受客户连接,我们需要使用系统调用来创建一个监听队列以存放待处理的客户连接,启动监听,不阻塞。

函数参数:

①socket 指定要被监听的socket。
②backlog 提示内核监听队列的最大长度。监听队列的长度如果超过了backlog,服务器将不受理新的客户连接,客户端也受到ECONNREFUSED错误信息2.2版本之后,其表示完全连接状态的socket的上限。backlog参数的典型值为5。

系统调用函数4:accept //接受连接

函数原型:

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

函数参数:

①sockfd 是执行过listen系统调用的监听socket。
②addr 用来获取被接受连接的远端 socket的地址。
③addrlen 2中地址长度由addrlen参数指出。

函数解释:

该函数只是从监听队列中取出连接,而不论连接处于何种状态(ESTABLISHED状态和CLOSE_WAIT状态),更不关心任何网络状况的变化。

函数返回值:

当accept成功的时间返回一个新的连接的sockfd。

 

系统调用函数5:connect //发起连接

函数原型:

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

函数参数:

①serv_addr 是服务器监听的socket地址
②addrlen 指定了这个地址的长度。

函数返回值:

成功 一旦连接成功,sockfd就唯一地标识了这个连接,客户端就可以读写sockfd来和服务器通信。
失败 两种情况 ECONNREFUSED目标端口不在,连接被拒绝;ETIMEDOUT,连接超时。

函数6:TCP数据读写

函数原型:

ssize_t recv(int sockfd,void *buf ,size_t len,int flag);//读取

ssize_t send(int sockfd,const void *buf,size_t len,int flags);//写数据

函数解释:

recv是读取sockfd上的数据  
buf和len 指定读取缓冲区的位置和大小
flag 为数据收发提供的额外控制,通常设置为0。

函数返回值

成功 返回实际读取到的数据的长度,可能小于我们期望的len,返回0,表明对方已经关闭连接了。
失败 失败返回-1.

函数7:close //关闭连接

函数原型:

int close(int fd);

函数参数: 

fd

fd 待关闭的socket的sockfd。close系统调用并非总是立即关闭一个连接,而是将fd的引用计数减一,只有当fd为0时,才真正关闭连接。

 

UDP读写函数:

函数原型:

recvfrom函数: ssize_trecvfrom(int sockfd,void* buf,size_t len, int flags,struct sockaddr* arc_addr,socklen_t* addrlen);
sendto函数: ssize_t sendto( int sockfd,const void* buf,size_t len,int flags,const struct sockaddr* dest_addr,socklen_t addrlen);

函数介绍:

  recvfrom/sendto系统调用函数也可以用于面向连接(STREAM)的socket的数据读写,只需要把最后两个参数都设置为NULL以忽略发送端/接收端的socket的地址(因为我们已经和对方建立了链接,所以已经知道其socket地址。)   

recvfrom功能: 读取sockfd上的数据,UDP通信没有连接的概念,所以我们每次读取的数据都需要获取发送端的socket地址,即参数src_addr所指的内容。
sendto功能: 往sockfd上写数据,dest_addr参数指定接收端的socket地址。

 参数介绍:

buf,和 len分别指定读/写缓冲区的位置和大小  
src_addr 和 dest_addr分别表示该缓冲区的位置信息  

2012-07-04 17:57:53 jzp12 阅读数 613
1)
示例代码有明显错误,但不失为好的参考文件

Linux下Socket编程

IBM文档库:

Linux socket 编程,第一部分
http://www.ibm.com/developerworks/cn/education/linux/l-sock/index.html

Linux socket 编程,第二部分
http://www.ibm.com/developerworks/cn/education/linux/l-sock2/index.html

2)

异步回收fork出的子进程(僵尸进程)


3)

Beej 的 Unix 进程间通讯指南

http://www.lslnet.com/linux/books/resource/default.htm


服务器/客户端文件传输
http://www.oldlinux.org/oldlinux/archiver/?tid-3409.html

2013-02-28 21:25:53 bg2bkk 阅读数 4938

之前一直在纠结这个怎么做,其实就是一个读写文件的流程,需要配置下串口的参数。

不过有意思的地方更在于,一,串口是可以作为终端的,linux终端tty是很有意思的,二,串口的配置涉及缓冲区设计,这点又和C语言的缓冲区息息相关,很多公司也喜欢考这样的C语言问题。

参考文献为:http://www.ibm.com/developerworks/cn/linux/l-serials/index.html

                        http://book.51cto.com/art/200711/59766.htm#book_content

                        http://book.51cto.com/art/200711/59758.htm

其中,IBM的源码为:

#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>
#include<sys/types.h>
#include<sys/stat.h>
#include<fcntl.h>
#include<termios.h>
#include<errno.h>

#define FALSE -1
#define TRUE 0

int speed_arr[] = { B38400, B19200, B9600, B4800, B2400, B1200, B300,B38400, B19200, B9600, B4800, B2400, B1200, B300, };
int name_arr[] = {38400,  19200,  9600,  4800,  2400,  1200,  300, 38400, 19200,  9600, 4800, 2400, 1200,  300, };
void set_speed(int fd, int speed){
  int   i; 
  int   status; 
  struct termios   Opt;
  tcgetattr(fd, &Opt); 
  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]);   
      status = tcsetattr(fd, TCSANOW, &Opt);  
      if  (status != 0) {        
        perror("tcsetattr fd1");  
        return;     
      }    
      tcflush(fd,TCIOFLUSH);   
    }  
  }
}

int set_Parity(int fd,int databits,int stopbits,int parity)
{ 
	struct termios options; 
	if  ( tcgetattr( fd,&options)  !=  0) { 
		perror("SetupSerial 1");     
		return(FALSE);  
	}
	options.c_cflag &= ~CSIZE; 
	switch (databits) 
	{   
	case 7:		
		options.c_cflag |= CS7; 
		break;
	case 8:     
		options.c_cflag |= CS8;
		break;   
	default:    
		fprintf(stderr,"Unsupported data size\n"); return (FALSE);  
	}
	switch (parity) 
	{   
		case 'n':
		case 'N':    
			options.c_cflag &= ~PARENB;   /* Clear parity enable */
			options.c_iflag &= ~INPCK;     /* Enable parity checking */ 
			break;  
		case 'o':   
		case 'O':     
			options.c_cflag |= (PARODD | PARENB); 
			options.c_iflag |= INPCK;             /* Disnable parity checking */ 
			break;  
		case 'e':  
		case 'E':   
			options.c_cflag |= PARENB;     /* Enable parity */    
			options.c_cflag &= ~PARODD;    
			options.c_iflag |= INPCK;       /* Disnable parity checking */
			break;
		case 'S': 
		case 's':  /*as no parity*/   
		    options.c_cflag &= ~PARENB;
			options.c_cflag &= ~CSTOPB;break;  
		default:   
			fprintf(stderr,"Unsupported parity\n");    
			return (FALSE);  
		}  
	
	switch (stopbits)
	{   
		case 1:    
			options.c_cflag &= ~CSTOPB;  
			break;  
		case 2:    
			options.c_cflag |= CSTOPB;  
		   break;
		default:    
			 fprintf(stderr,"Unsupported stop bits\n");  
			 return (FALSE); 
	} 
	/* Set input parity option */ 
	if (parity != 'n')   
		options.c_iflag |= INPCK; 
	tcflush(fd,TCIFLUSH);
	options.c_cc[VTIME] = 150; 
	options.c_cc[VMIN] = 0; /* Update the options and do it NOW */
	if (tcsetattr(fd,TCSANOW,&options) != 0)   
	{ 
		perror("SetupSerial 3");   
		return (FALSE);  
	} 
	return (TRUE);  
}

int main()
{
	printf("STDIO COM1\n");
	int fd;
	fd = open("/dev/ttyS0",O_RDWR);
	if(fd == -1)
	{
		perror("serialport error\n");
	}
	else
	{
		printf("open ");
		printf("%s",ttyname(fd));
		printf(" succesfully\n");
	}

	set_speed(fd,115200);
	if (set_Parity(fd,8,1,'N') == FALSE)  {
		printf("Set Parity Error\n");
		exit (0);
	}
	char buf = 'c';
	write(fd,&buf,1);
	close(fd);
	return 0;
}


51cto的这本书讲解较为详细,对每项参数有详细解释:

#include<stdio.h>
#include<stdlib.h>
#include<fcntl.h>
#include<unistd.h>
#include<errno.h>
#include<termios.h>
#include<sys/types.h>
#include<sys/stat.h>
int main()
{
	printf("COM1 test program\n");
	int fd;
	fd = open("/dev/ttyS0",O_RDWR);
	if(fd == -1)
	{
		perror("serialport error\n");
	}
	else{
		printf("open %s succesfully\n", ttyname(fd));
	}

	struct termios Opt;
	int status;
	
	tcgetattr(fd, &Opt);
	//set speed
	cfsetispeed(&Opt, B115200);
	cfsetospeed(&Opt, B115200);
	//set databits
	Opt.c_cflag &= ~CSIZE;
	Opt.c_cflag |= CS8;
	//set parity
	Opt.c_cflag &= ~PARENB;
	Opt.c_iflag &= ~INPCK;
	//set stopbits
	Opt.c_cflag &= ~CSTOPB;
	tcsetattr(fd, TCSANOW, &Opt);
	status = tcsetattr(fd, TCSANOW, &Opt);
	if(status != 0)
	{
		perror("tcsetattr fd1");
		return;
	}

	char buf = 'd';
	write(fd, &buf, 1);
	close(fd);
	
	return 0;
}


2007-09-08 18:20:00 misterliwei 阅读数 2029

参考文献

 

 

1. 李贵山、陈金鹏主编,PCI局部总线及其应用,西安电子科技大学出版社

2. Ravi Budruk等著、田玉敏等译,PCI Express系统体系结构标准教材,电子工业出版社

3. 毛德操, 胡希明,LINUX内核源代码情景分析 上下册,浙江大学出版社

4.尹士闪,DOS模式下PCI设备的识别,石家庄铁路职业技术学院学报,20053

5. PCI Local Bus Specification Revision 2.2 1988-12-18

6. REALTEK公司,REL8139C DATASHEETV1.6

7. STMicroelectronics GROUP, M27C256B DATASHEET

8.李全忠,王希超,直接读取PCI网卡的MAC地址的原理与方法,计算机工程,20059

 
2015-07-07 09:35:00 weixin_30691871 阅读数 4

首先要说讲述TCP/IP的书很多,其中有3泰书很全。

分别是《TCP/IP详解》三卷本,《用TCP/IP进行网际互连》三卷本,《TCP/IP指南》+《IPv6》四卷本

其中TCP/IP详解的作者还写了另外2本经典著作,《Unix环境高级编程》,《Unix网络编程》

作者W.Richard Stevens个人网站  http://www.kohala.com/

大师作品部部经典,可惜1999年去另一个世界维护Unix了。。。。。。。。。

 

说明:搞Linux网络编程的,想学TCP/IP的一定要看大师W.Richard Stevens这六本书,基本上六本书看完基础也就搭好了。

 

 

 

 

W.Richard Stevens(1951-1999),国际知名的UNIX和网络专家,受人人尊敬的作家。他的著作有《UNIX网络编程》(两卷本),《UNIX网络高级编程》,《TCP/IP详解》(三卷本)等,同时他还是广受欢迎的教师和顾问。 

  Stevens先生1951年生于赞比亚,早年,他就读于美国弗吉尼亚州的费什本军事学校,后获得密歇根大学学士、亚利桑那大学系统工程硕士和博士学位。他曾就职于基特峰国家天文台,从事计算机编程。 

  Stevens先生不幸病逝于1999年9月1日,他的离去是计算机界的巨大损失。 

  W. Richard Stevens对我们这些学习Unix/Linux的程序员的影响是巨大的,每每捧读老先生的书都会被感动,不仅被他那丰富的知识所折服,更是被他那一丝不苟,严谨治学的态度所倾倒。“他不清楚的,他下决心要弄明白。他知道的,他要努力传授给所有感兴趣的人们!”这就是我们的Stevens!一生能有其一部力作可谓无憾矣!而况七部乎? 

  一位朋友说:“Stevens的书一定要全部认真地去读的。”我想他是对的。最后,对Stevens在天英灵说声:谢谢您!想必这时他正坐在上帝身边,继续从事他的写作。 

W. Richard Stevens Biography 
http://www.kohala.com/start/bio1.html 

W. Richard Stevens' Home Page 
http://www.kohala.com/start/ 

W. Richard Stevens on Wikipedia 
http://en.wikipedia.org/wiki/W._Richard_Stevens 

Guru of the Unix gurus 
http://archive.salon.com/tech/feature/2000/09/01/rich_stevens/index.html

----------------------------------------------------------------------------------------------------------------------------------------------------------------

《用TCP/IP进行网际互连第一卷:原理、协议与结构(第五版)》

《用TCP/IP进行网际互连第二卷——设计、实现与内核》

《用TCP/IP进行网际互连第三卷:客户-服务器编程与应用(Linux/POSIX套接字版)》

说明:这个系列也是三卷本,和《TCP/IP详解》三卷本一样也是经典,区别是  网际互联 偏重理论而 详解偏重实际。

----------------------------------------------------------------------------------------------------------------------------------------------------------------

如果你看了上面2套TCP/IP的书6本还不尽兴,还有一套书可以作为提高或者查缺补漏

虽然与W.Richard Stevens TCP/IP详解 有一定的差距,但仍不失为下一代IPv6网络的参考工具书,值得收藏学习

 

----------------------------------------------------------------------------------------------------------------------------------------------------------------

 

《TCP/IP协议原理与应用(第3版)》

写的非常好,建议一定要买!可作入门,但即使是高手,也应看看,学习作者分析问题的方法和思想。其实是无数次印刷了,经典不能错过。

----------------------------------------------------------------------------------------------------------------------------------------------------------------

《TCP/IP高效编程 : 改善网络程序的44个技巧》

很明显属于技巧类的书,同样这本书很老,但是还是很有参考价值,这本书中大量出现Unix网络编程的提示,可以作为其补充。

----------------------------------------------------------------------------------------------------------------------------------------------------------------

《TCP/IP架构、设计及应用(Linux版)》

谈不上经典,可以补充阅读

----------------------------------------------------------------------------------------------------------------------------------------------------------------

《linux网络体系结构:linux内核中网络协议的设计与实现》

出版社: 清华大学出版社
装帧: 平装
出版年: 2006-7
又名: The Linux Network Architecture: Design and Implementation of Network Protocols in the Linux Kernel
书名: Linux网络体系结构
说明:翻译的很不好,建议看原版,可以下电子版。

一本在kernel实现网络功能的基础书籍,最好还是看英文版的,翻译的实在太烂了。有条件的还是看原版吧,没办法啊,中国的此类书籍基本上落后老美3-4年。结合linux源代码分析一书收获更多。一并把内核结构和各功能在内核中的关系也搞清楚了。

----------------------------------------------------------------------------------------------------------------------------------------------------------------

本人写的另外系列,配合一起看效果更好,因为C语言是语言,还需要到实际环境Linux中去用,而Linux环境下网络编程自然需要TCP/IP的知识:

转载于:https://www.cnblogs.com/jiangzhaowei/p/4626040.html

Linux Shell编程初步

阅读数 1161

没有更多推荐了,返回首页