linux 的套接字

套接字是一种通信机制,凭借这种机制,客户/服务器系统的开发工作既可以在本地单机上进行,也可以跨网络进行。

套接字的特性有三个属性确定,它们是:域(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.套接字协议

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

创建套接字

socket系统调用创建一个套接字并返回一个描述符,该描述符可以用来访问该套接字。

#include<sys/types.h>

#include<sys/socket.h>

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

创建的套接字是一条通信线路的一个端点。domain参数指定协议族,type参数指定这个套接字的通信类型,protocol参数指定使用的协议。

domain参数可以指定的协议族如下

域 说明

AF_UNIX  UNIX域协议(文件系统套接字)

AF_INET  ARPA因特网协议(UNIX网络套接字)

AF_ISO  ISO标准协议

AF_NS  施乐(XEROX)网络系统协议

AF_IPX  NOVELL IPX协议

AF_APPLETALKAppletalk DDS

最常见的套接字域是AF_UNIX和AF_INET,前者用于通过Unix和Linux文件系统实现的本地套接字,后者用于Unix网络套接字。AF_INET套接字可以用于通过包括因特网在内的TCP/IP网络进行通信的程序。微软Windows系统的winsock接口也提供了对这个套接字域的访问功能。

socket函数的参数type指定用于新套接字的通信特性。它的取值包括SOCK_STREAM和SOCK_DGRAM。

SOCK_STREAM是一个有序、可靠、面向连接的双字节流。通过TCP连接来实现。

SOCK_DGRAM是数据包服务,我们可以用它来发送最大长度固定的消息。但消息是否会被正确传递或消息是否不会乱序到达没有保证。

套接字地址结构

结构struct sockaddr_un 定义了一种通用的套接字地址,它的类型是:

struct sockaddr_un

{

sa_family_t sun_family;       /*AF_UNIX*/

char              sun_path;         /*pathname*/

};

这是一种通用的定义,一般都不用。TCP/IP使用的是自己的结构体struct sockaddr_in,格式如下:

struct sockaddr_in

{

short int sin_family;      //地址类型,一般为AF_INET

unsigned short int sin_port;        //端口号

struct in_addr sin_addr;        //IP地址

};

这里的struct in_addr的定义如下:

struct in_addr

{

unsigned long int  s_addr;

};

结构体sockaddr和sockaddr_in的长度都是16字节。一般在编TCP/IP程序时,一般使用结构体sockaddr_in来设置地址,然后在需要的时候,通过强制类型转换成sockaddr类型。

建立连接

函数connect用来在一个指定的套接字上创建一个连接,函数原型:

[cpp] view plain copy print?

  1. int connect(int socket, const struct sockaddr *address, size_t address_len);

参数sockfd是一个由函数socket创建的套接字;

参数address是一个地址结构,需要连接的地址;

参数address_len为参数addr_addr的长度。

函数执行成功返回0,有错误发生则返回-1。

如果套接字类型是TCP,则该函数用于向服务器发出连接请求,服务器的IP地址和端口号由参数serv_addr指定;如果套接字类型是UDP,则该函数并不建立真正的连接,它只是告诉内核与该套接字进行通信的目的地址(由第二个参数指定),只有该目的地址发来的数据才会被该socket接收。

通常一个面向连接的套接字只能调用一次connect函数;而对于无连接的套接字则可以多次调用connect函数以改变与目的地址的绑定。

在套接字上监听

函数listen把套接字转化为被动监听,函数原型:

int listen(int s, int backlog);

参数s指定了一个套接字;

参数backlog指定了该连接队列的最大长度,如果已达到最大,则之后的连接请求将被服务器拒绝。

函数执行成功赶回0,有错误发生则返回-1。

由函数socket创建的套接字是主动套接字,这种套接字可以用来主动请求连接到某个服务器上。(通过connect()函数)。

作为服务器端的程序,通常在某个端口上监听等待来自客户端的连接请求。在服务器端,一般是先调用函数socket创建一个主动套接字,然后调用函数bind将该套接字绑定到某个端口上,接着再调用函数listen将该套接字转化为监听套接字,等待来自于客户端的连接请求。

函数listen只是将套接字设置为倾听模式以等待连接请求,它并不能接收连接请求,真正的接收客户端连接请求的是accept()函数。

接收连接

函数accept用来接收一个连接请求,函数原型:

int accept(int s, struct sockaddr *addr, socklen_t *addrlen);

参数s是由socket创建,经函数bind绑定到本地某一端口上,然后通过函数listen转化而来的监听套接字;

参数addr用来保存发起连接请求的主机的地址和端口;

参数addrlen是addr所指向的结构体的大小。

函数执行成功返回一个新的代表客户端的套接字,出错则返回-1。

只能对面向连接的套接字使用accept函数。accept执行成功时,将创建一个新的套接字,并且这个新的套接字分配一个套接字描述符,并返回这个新的套接字描述符。这个新的套接字描述符与打开文件返回的文件描述符类似,进程可以利用这个新的套接字描述符与客户端交换数据,参数s所指定的套接字继续等待客户端的连接请求。

[cpp] view plain copy print?

  1. /*  Make the necessary includes and set up the variables.  */
  2. #include <sys/types.h>
  3. #include <sys/socket.h>
  4. #include <stdio.h>
  5. #include <sys/un.h>
  6. #include <unistd.h>
  7. #include <stdlib.h>
  8. int main()
  9. {
  10. int sockfd;
  11. int len;
  12. struct sockaddr_un address;
  13. int result;
  14. char ch = ‘A‘;
  15. /*  Create a socket for the client.  */
  16. sockfd = socket(AF_UNIX, SOCK_STREAM, 0);
  17. /*  Name the socket, as agreed with the server.  */
  18. address.sun_family = AF_UNIX;
  19. strcpy(address.sun_path, "server_socket");
  20. len = sizeof(address);
  21. /*  Now connect our socket to the server‘s socket.  */
  22. result = connect(sockfd, (struct sockaddr *)&address, len);
  23. if(result == -1) {
  24. perror("oops: client1");
  25. exit(1);
  26. }
  27. /*  We can now read/write via sockfd.  */
  28. write(sockfd, &ch, 1);
  29. read(sockfd, &ch, 1);
  30. printf("char from server = %c\n", ch);
  31. close(sockfd);
  32. exit(0);
  33. }

[cpp] view plain copy print?

  1. /*  Make the necessary includes and set up the variables.  */
  2. #include <sys/types.h>
  3. #include <sys/socket.h>
  4. #include <stdio.h>
  5. #include <sys/un.h>
  6. #include <unistd.h>
  7. #include <stdlib.h>
  8. int main()
  9. {
  10. int server_sockfd, client_sockfd;
  11. int server_len, client_len;
  12. struct sockaddr_un server_address;
  13. struct sockaddr_un client_address;
  14. /*  Remove any old socket and create an unnamed socket for the server.  */
  15. unlink("server_socket");
  16. server_sockfd = socket(AF_UNIX, SOCK_STREAM, 0);
  17. /*  Name the socket.  */
  18. server_address.sun_family = AF_UNIX;
  19. strcpy(server_address.sun_path, "server_socket");
  20. server_len = sizeof(server_address);
  21. bind(server_sockfd, (struct sockaddr *)&server_address, server_len);
  22. /*  Create a connection queue and wait for clients.  */
  23. listen(server_sockfd, 5);
  24. while(1) {
  25. char ch;
  26. printf("server waiting\n");
  27. /*  Accept a connection.  */
  28. client_len = sizeof(client_address);
  29. client_sockfd = accept(server_sockfd,
  30. (struct sockaddr *)&client_address, &client_len);
  31. /*  We can now read/write to client on client_sockfd.  */
  32. read(client_sockfd, &ch, 1);
  33. ch++;
  34. write(client_sockfd, &ch, 1);
  35. close(client_sockfd);
  36. }
  37. }
时间: 2024-10-08 17:19:33

linux 的套接字的相关文章

linux netlink套接字学习资料

理论: http://blog.csdn.net/unbutun/article/details/3394061 进一步深入: http://edsionte.com/techblog/archives/4134 http://edsionte.com/techblog/archives/4140 http://edsionte.com/techblog/archives/4134 实践: http://bbs.chinaunix.net/thread-3766684-1-1.html 附录代码

linux netlink套接字实现类似ss命令 ,统计套接字以及TCP信息

参考了 ss的源代码 以及 netlink相关资料:http://blog.csdn.net/scdxmoe/article/details/27711205 实现结果为: gcc netlink_dig_530_7.c -o netlink_dig_530_7 ./netlink_dig_530_7 state      family     l.addr     l.port       r.addr     r.rport LISTEN     AF_INET   localhost  

Linux编程---套接字

网络相关的东西几乎都是建立在套接字之上.所以这个内容对于程序员来说还是蛮重要的啊. 其实套接字也就是一个特殊的设备文件而已,我始终不能明白为什么要叫套接字.这么个奇怪的名字.不过还是就这样算了吧.关键还是编程上.由于其重要性,我还是写的详细一点吧. 一.套接字 核心函数: int  socket(int domain,int type,int protocol); 这个函数在通信域domain中创建一个类型为type,使用协议protocol的套接字.并且返回一个描述字,也就是相当于打开了一个特

Linux 原始套接字--myping的实现

一.套接字的类型 A.流套接字(SOCK_STREAM) 用于提供面向连接.可靠的数据传输服务,其使用传输层的TCP协议 B.数据报套接字(SOCK_DGRAM) 用于提供一个无连接.不可靠的服务,其使用传输层上的UDP协议 C.原始套接字(SOCK_RAM) 原始套接字是相对表中套接字(即前面两种套接字)而言的.它与标准套接字的区别是原始套接字可以读写内核没有处理的IP数据包,流套接字只能读取TCP协议的数据,数据报套接字只能读取UDP协议的数据. 所以要访问其他协议的数据必须使用原始套接字.

关于linux 原始套接字编程

关于linux 网络编程最权威的书是<<unix网络编程>>,但是看这本书时有些内容你可能理解的不是很深刻,或者说只知其然而不知其所以然,那么如果你想搞懂的话那么我建议你可以看看网络协议栈的实现. 函数原型是 int socket(int domain, int type, int protocol); 其中domain 中AF_INET , AF_UNIT 较为常用,分别创建inet 域套接字和unix域套接字,unix套接字与文件相关.平时80%用的套接字都是AF_INET.这

分析linux中套接字的实现-------创建

套接字是一种使用系统的文件描述符和系统进程进行通信的一种方法. 1.下面是描述套接字地址的结构体: struct sockaddr { sa_family_t sa_family; /* address family, AF_xxx */ 如果使用了tcp/ip协议,AF_INET char sa_data[14]; /* 14 bytes of protocol address */ }; 2.socket的系统调用: 我们创建套接字都是用socket来创建. socket的系统调用: //每

LINUX TCP套接字详细配置

提高服务器的负载能力,是一个永恒的话题.在一台服务器CPU和内存资源额定有限的情况下,最大的压榨服务器的性能,是最终的目的.要提高 Linux系统下的负载能力,可以先启用Apache的Worker模式,来提高单位时间内的并发量.但是即使这么做了,当网站发展起来之后,连接数过多 的问题就会日益明显.在节省成本的情况下,可以考虑修改Linux的内核TCP/IP参数,来最大的压榨服务器的性能.当然,如果通过修改内核参数也无法 解决的负载问题,也只能考虑升级服务器了,这是硬件所限,没有办法的事. Lin

linux程序设计——套接字选项(第十五章)

现在可以改进客户程序,使它可以连接到任何有名字的主机,这次不是连接到示例服务器,而是连接到一个标准服务,这样就可以演示端口号的提取操作了. 大多数UNIX和一些linux系统都有一项标准服务daytime,它提供系统的日期和时间.客户可以连接到这个服务来查看服务器的当前日期和时间.下面就是完成这一工作的客户程序getdate.c 编写程序getdate.c /*********************************************************************

Linux/UNIX套接字连接

套接字连接 套接字是一种通信机子.凭借这样的机制.客户/server系统的开发工作既能够在本地单机上进行.也能够夸网络进行. 套接字的创建和使用与管道是有差别的.由于套接字明白地将客户和server区分开来. 套接字连接: 首先,server应用程序用系统调用socket来创建一个套接字,它是系统分配给该server进程的类似文件描写叙述符的资源,它不能与其它进程共享. 接下来.server进程会给套接字起个名字.本地套接字的名字是Linux文件系统中的文件名称,对于网络套接字它的名字是与客户连