失眠网,内容丰富有趣,生活中的好帮手!
失眠网 > Socket编程(C语言实现)——UDP协议(进程间通信AF_UNIX)的流式(SOCK_STREAM)+报

Socket编程(C语言实现)——UDP协议(进程间通信AF_UNIX)的流式(SOCK_STREAM)+报

时间:2021-01-26 12:55:50

相关推荐

Socket编程(C语言实现)——UDP协议(进程间通信AF_UNIX)的流式(SOCK_STREAM)+报

Socket编程

目前较为流行的网络编程模型是客户机/服务器通信模式

客户进程向服务器进程发出要求某种服务的请求,服务器进程响应该请求。如图所示,通常,一个服务器进程会同时为多个客户端进程服务,图中服务器进程B1同时为客户进程A1、A2和B2提供服务。

Socket概述

① 所谓Socket通常也称作“套接字”,用于描述IP地址和端口,是一个通信链的句柄。应用程序通常通过“套接字”向网络发出请求或者应答网络请求。

② Socket是连接运行在网络上的两个程序间的双向通信的端点。

③ 网络通讯其实指的就是Socket间的通讯。

④ 通讯的两端都有Socket,数据在两个Socket之间通过IO来进行传输。

套接字socket的类型

(1)流式套接字(SOCK_STREAM)

提供面向连接、可靠的数据传输服务,数据无差错、无重复的发送,且按发送顺序接收(TCP协议)

(2)数据报式套接字(SOCK_DGRAM)

提供无连接服务,数据包以独立包形式发送,不提供无措保证,数据可能丢失,并且接收顺序混乱(UDP协议)

(3)原始套接字(SOCK_RAM)

套接字(socket)

socket起源于Unix,而Unix/Linux基本哲学之一就是“一切皆文件”,都可以用“打开open –> 读写write/read –> 关闭close”模式来操作。Socket就是该模式的一个实现,socket即是一种特殊的文件,一些socket函数就是对其进行的操作(读/写IO、打开、关闭).说白了Socket是应用层与TCP/IP协议族通信的中间软件抽象层,它是一组接口。在设计模中,Socket其实就是一个门面模式,它把复杂的TCP/IP协议族隐藏在Socket接口后面,对用户来说,一组简单的接口就是全部,让Socket去组织数据,以符合指定的协议。

随着Unix的应用推广,套接字有被引进了windows等操作系统。套接字通常只与同一区域的套接字交换数据,windows socket只支持一个通信区域:网际域(AF_INET),这个域被使用忘记协议簇的通信进程使用。

基于UDP(面向无连接)的socket编程

报式传输:“客户端”,1.socket()函数;2.bind()函数,绑定客户端的地址与端口【网络间通信AF_STREAM】或者路径【进程间通信AF_DGRAM】,以便于后续服务端sendto()函数参数的填写。若服务器端只是收不发数据,即,服务端有recvfrom()函数无sendto()函数,则客户端不需要bind()函数;若服务端要发送数据,即,有sendto()函数,则客户端需要bind()函数;3.客户端sendto()函数参数,填写服务端的地址与端口【网络间通信AF_STREAM】或者服务端路径【进程间通信AF_DGRAM】的结构体地址与结构体长度,服务端必须有bind()函数;4.客户端recvfrom()函数参数,NULL,会自动识别。

报式传输:“服务端”,1.socket()函数;2.bind()函数,绑定客户端的地址与端口【网络间通信AF_STREAM】或者路径【进程间通信AF_DGRAM】,以便于后续客户端sendto()函数参数的填写。若服务器端只是收不发数据,即,服务端有recvfrom()函数无sendto()函数,则客户端不需要bind()函数;3.服务端sendto()函数参数,填写客户端的地址与端口【网络间通信AF_STREAM】或者客户端路径【进程间通信AF_DGRAM】的结构体地址与结构体长度,服务端必须有bind()函数;4.recvfrom()函数参数,NULL,会自动识别。

基于UDP(面向无连接)的socket编程(循环监听)——流式套接字(SOCK_STREAM)

进程间通信AF_UNIX,典型的本地进程间通信

服务器:

#include <stdio.h>#include <sys/types.h>#include <sys/socket.h>#include <sys/un.h>int main(){int iSocketFD = 0;int iNewFD = 0;struct sockaddr_un stLocalAddr = {0};char acBuf[1024]= {0};iSocketFD = socket(AF_UNIX, SOCK_STREAM, 0);if(0 > iSocketFD){printf("创建socket失败!\n");return 0;}stLocalAddr.sun_family = AF_UNIX;sprintf(stLocalAddr.sun_path, "./xxx");remove("./xxx");if(0 > bind(iSocketFD, (void *)&stLocalAddr, sizeof(stLocalAddr))){close(iSocketFD);printf("绑定地址失败!\n");return -1;}if(0 > listen(iSocketFD, 5)){close(iSocketFD);printf("监听失败!\n");return -1;}while(1){iNewFD = accept(iSocketFD, NULL, NULL);if(0 > iNewFD){close(iSocketFD);printf("接收数据失败!\n");return -1;}if(0 > recv(iNewFD, acBuf, sizeof(acBuf), 0)){close(iSocketFD);close(iNewFD);printf("接收失败!\n");return -1;}else{printf("接收到的客户端发来的信息是:%s\n", acBuf);}if(0 > send(iNewFD, "服务器", sizeof("服务器"), 0)){close(iSocketFD);close(iNewFD);printf("发送失败!\n");return -1;}}return 0;}

客户端:

#include <stdio.h>#include <sys/socket.h>#include <sys/un.h>#include <sys/types.h>int main(){int iSocketFD = 0;struct sockaddr_un stRemoteAddr = {0};char acBuf[1024] = {0};iSocketFD = socket(AF_UNIX, SOCK_STREAM, 0);if(0 > iSocketFD){printf("创建socket失败!\n");return -1;}//填充对端地址stRemoteAddr.sun_family = AF_UNIX;sprintf(stRemoteAddr.sun_path,"./xxx"); //注意用sprintf//注意connect的第二个参数if(0 > connect(iSocketFD, (void *)&stRemoteAddr, sizeof(stRemoteAddr))){close(iSocketFD);printf("连接服务器失败!\n");return -1;}if(0 > send(iSocketFD, "客户端", sizeof("客户端"), 0)){close(iSocketFD);printf("发送数据失败!\n");return -1;}if(0 > recv(iSocketFD, acBuf, sizeof(acBuf), 0)){close(iSocketFD);printf("接收数据失败!\n");return -1;}printf("客户端接收到服务器发来的消息是:%s\n", acBuf);return 0;}

测试:

1、编译服务器、客户端代码:

[root@localhost unix_stream]# make socket_client_streamccsocket_client_stream.c -o socket_client_stream[root@localhost unix_stream]# make socket_server_streamccsocket_server_stream.c -o socket_server_stream

2、执行服务端代码:

[root@localhost unix_stream]# ./socket_server_stream接收到的客户端发来的信息是:客户端接收到的客户端发来的信息是:客户端

3、执行客户端代码:

[root@localhost unix_stream]# ./socket_client_stream客户端接收到服务器发来的消息是:服务器[root@localhost unix_stream]# ./socket_client_stream客户端接收到服务器发来的消息是:服务器

基于UDP(面向无连接)的socket编程——数据报式套接字(SOCK_DGRAM)

进程间通信AF_UNIX,典型的本地进程间通信

服务器:( 循环监听)

#include <stdio.h>#include <sys/types.h>#include <sys/socket.h>#include <sys/un.h>int main(){int iSocketFD = 0;int iNewFD = 0;struct sockaddr_un stLocalAddr = {0};struct sockaddr_un stRemoteAddr = {0};char acBuf[1024]= {0};iSocketFD = socket(AF_UNIX, SOCK_DGRAM, 0);if(0 > iSocketFD){printf("创建socket失败!\n");return 0;}stLocalAddr.sun_family = AF_UNIX;sprintf(stLocalAddr.sun_path, "./server");remove("./server");//绑定之前要删除原来的文件if(0 > bind(iSocketFD, (void *)&stLocalAddr, sizeof(stLocalAddr))){close(iSocketFD);printf("绑定地址失败!\n");return -1;}stRemoteAddr.sun_family = AF_UNIX;sprintf(stRemoteAddr.sun_path, "./client");while(1){if(0 > recvfrom(iSocketFD, acBuf, sizeof(acBuf), 0, NULL, NULL)){close(iSocketFD);printf("接收失败!\n");return -1;}else{printf("接收到的客户端发来的信息是:%s\n", acBuf);}if(0 > sendto(iSocketFD, "服务器", sizeof("服务器"), 0, (void *)&stRemoteAddr, sizeof(stRemoteAddr))){close(iSocketFD);printf("发送失败!\n");return -1;}}return 0;}

客户端:

#include <stdio.h>#include <sys/socket.h>#include <sys/un.h>#include <sys/types.h>int main(){int iSocketFD = 0;struct sockaddr_un stRemoteAddr = {0};struct sockaddr_un stLocalAddr = {0};char acBuf[1024] = {0};iSocketFD = socket(AF_UNIX, SOCK_DGRAM, 0);if(0 > iSocketFD){printf("创建socket失败!\n");return -1;}stLocalAddr.sun_family = AF_UNIX;sprintf(stLocalAddr.sun_path, "./client"); //注意用sprintfremove("./client");//绑定之前要删除原来的if(0 > bind(iSocketFD, (void *)&stLocalAddr, sizeof(stLocalAddr))){printf("绑定地址失败!\n");return -1;}//填充对端地址//报式传输,只发不收可以不bind,要发要收必须要bindstRemoteAddr.sun_family = AF_UNIX;sprintf(stRemoteAddr.sun_path, "./server"); //注意用sprintfif(0 > sendto(iSocketFD, "客户端", sizeof("客户端"), 0, (void *)&stRemoteAddr, sizeof(stRemoteAddr))){close(iSocketFD);printf("发送数据失败!\n");return -1;}if(0 > recvfrom(iSocketFD, acBuf, sizeof(acBuf), 0, NULL, NULL)){close(iSocketFD);printf("接收数据失败!\n");return -1;}printf("客户端接收到服务器发来的消息是:%s\n", acBuf);return 0;}

测试:

1、编译服务器和客户端:

[root@localhost unix_dgram]# make socket_client_dgramccsocket_client_dgram.c -o socket_client_dgram[root@localhost unix_dgram]# make socket_server_dgramccsocket_server_dgram.c -o socket_server_dgram

2、服务器监听:

[root@localhost unix_dgram]# ./socket_server_dgram接收到的客户端发来的信息是:客户端接收到的客户端发来的信息是:客户端

3、客户端连接服务器:

[root@localhost unix_dgram]# ./socket_client_dgram客户端接收到服务器发来的消息是:服务器[root@localhost unix_dgram]# ./socket_client_dgram客户端接收到服务器发来的消息是:服务器

参考链接:/zhang___yong/article/details/78702559

java:/wzy330782/p/5479833.html

基于TCP/IP和UDP协议的socket编程结构解析:/zhengnice/article/details/51428080

Socket编程(C语言实现)——UDP协议(进程间通信AF_UNIX)的流式(SOCK_STREAM)+报式(SOCK_DGRAM)传输【循环监听】

如果觉得《Socket编程(C语言实现)&mdash;&mdash;UDP协议(进程间通信AF_UNIX)的流式(SOCK_STREAM)+报》对你有帮助,请点赞、收藏,并留下你的观点哦!

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。