tcp socket 和 socket文件

来源:互联网 发布:单片机倒计时器设计 编辑:程序博客网 时间:2024/05/16 03:48
  • tcp socket
    tcp socket 是标示了一台主机的进程,是tcp连接中一端的实例。socket不是连接,只是表示了其中一端。由IP和port构成。
  • tcp 连接
    tcp连接由两台主机上的进程的socket连接构成。

tcp server

为建立tcp连接,扮演server角色的一端进程需要:

  • 通过socket()系统调用新建一个socket。
sockfd = socket(AF_INET, SOCK_STREAM, 0);
  • 给新建的socket绑定IP和port
bind(sockfd, (struct sockaddr *) &serv_addr, sizeof(serv_addr))

其中serv_addr结构体内包含了IP和port信息。

  • 通过listen()系统调用监听连接
listen(sockfd,5);
  • 通过accept()系统调用接收连接
newsockfd = accept(sockfd, (struct sockaddr *) &cli_addr, &clilen)

这里newsockfd是通过accept()系统调用新建的socket文件描述符。当server监听到连接请求,便用这个新生产的socket与远程client的socket通讯。
完整的程序server.c
server.c是一个多进程版本的tcp server,当有新的请求时,使用fork()系统调用产生新进程来处理连接请求:

     while (1) {         newsockfd = accept(sockfd,                (struct sockaddr *) &cli_addr, &clilen);         if (newsockfd < 0)              error("ERROR on accept");         pid = fork(); // 子进程处理连接         if (pid < 0)             error("ERROR on fork");         if (pid == 0)  {             close(sockfd);             dostuff(newsockfd);             exit(0);         }         else close(newsockfd);     } 

其实也可以用多线程来处理请求,当有新的请求时,使用pthread_create()调用,产生新线程。详细代码参考 这里。
其实最有效当处理多请求当手段是使用系统epoll,通过事件通知机制,non-blocking地处理请求。详细代码参考这里

tcp client

为了建立tcp连接,tcp client 做了下面这些事儿:

  • 新建socket
sockfd = socket(AF_INET, SOCK_STREAM, 0);
  • 通过系统调用connect(),与远程server监听socket发起连接请求。
connect(sockfd,&serv_addr,sizeof(serv_addr))
  • 连接成功后,便可通过向新建的socket中read()write()来实现通讯了。
n = write(sockfd,buffer,strlen(buffer));n = read(sockfd,buffer,255);

完整代码client.c

socket 文件

一切皆文件的Unix-like系统中,进程生产的socket通过socket文件来表示,进程通过向socket文件读写内容实现消息的传递。
在Linux系统中,通常socket文件在/proc/pid/fd文件下。通过上面的server.c和client.c实践一下,窥探一下对应的socket文件。

先编译server.c和client.c

gcc server.c -o server
gcc client.c -o client

运行在本地30000端口上:

server 30000

用lsof或者netstat查看server进程ID
这里写图片描述

根据pid(17009),去目录/proc/17009/fd下查看:
这里写图片描述
其中socket:[1293853508]便是socket文件。

运行client,连接到server上。

client localhost 30000

先不要发送消息,保持连接。然后通过 lsof命令查看30000端口:
这里写图片描述

看图中NAME这一列,其中
第一行,*:30000是server到监听socket文件名
第二行,localhost:57684->localhost:30000 (ESTABLISHED)是client端端socket文件名
第三行,localhost:30000->localhost:57684 (ESTABLISHED)是server 端为client端的请求建立的新的socket,负责和client通信

Unix Domain socket

上述所说的socket是internet domain socket,用于不同主机之间进程的通信。在Unix中,本机之间进程通信通常用另外一种socket( Unix domain socket)。新建Unix domain socket 连接和 internet domain socket 连接几乎上差不多,唯一的区别就是socket()系统调用时传入socket type 不同而已。

sockfd = socket(AF_UNIX,SOCK_STREAM,0

注意这里的 AF_UNIX 和 上面的AF_INET 区别。

Unix socket server程序userver.c

Unix socket client程序uclient.c

编译:

gcc userver.c -o userver
gcc uclientj.c -o uclient

userver 接收一个参数,用于创建socket文件,参数便是socket文件的名字。比如用 /tmp/usfd作为socket文件。

userver /tmp/usfd

查看一下新生产的socket文件:

ls -l /tmp/usfd
这里写图片描述

该文件的mode string的第一个字符s表示这是一个socket文件。

原创粉丝点击