socket和http区别,websocket和socket区别

首页 > 技术 > 作者:YD1662022-10-26 13:01:10

我们就可以简单的理解 HTTP 的数据结构了。

分享更多网络底层原理知识点,内容包括Nginx,ZeroMQ,MySQL,Redis,fastdfs,MongoDB,ZK,流媒体,CDN,P2P,K8S,Docker,TCP/IP,协程,DPDK等等。后台私信【架构】获取

Linux下的socket演示程序

下面用最基础的Socket来进行服务端与客户端的交互,让你理解的更为清晰。

接口详解

方法名

用途

socket():

创建socket

bind():

绑定socket到本地地址和端口,通常由服务端调用

listen():

TCP专用,开启监听模式

accept():

TCP专用,服务器等待客户端连接,一般是阻塞态

connect():

TCP专用,客户端主动连接服务器

send():

TCP专用,发送数据

recv():

TCP专用,接收数据

sendto():

UDP专用,发送数据到指定的IP地址和端口

recvfrom():

UDP专用,接收数据,返回数据远端的IP地址和端口

close():

关闭socket

基于TCP协议实现CS端

使用Socket进行网络通信的过程

① 服务器程序将一个套接字绑定到一个特定的端口,并通过此套接字等待和监听客户的连接请求。

② 客户程序根据服务器程序所在的主机和端口号发出连接请求。

③ 如果一切正常,服务器接受连接请求。并获得一个新的绑定到不同端口地址的套接字。

④ 客户和服务器通过读、写套接字进行通讯。

socket和http区别,websocket和socket区别(13)

客户机/服务器模式

在TCP/IP网络应用中,通信的两个进程间相互作用的主要模式是客户机/服务器模式*(client/server),即客户像服务其提出请求,服务器接受到请求后,提供相应的服务。

服务器:

(1)首先服务器方要先启动,打开一个通信通道并告知本机,它愿意在某一地址和端口上接收客户请求

(2)等待客户请求到达该端口

(3)接收服务请求,处理该客户请求,服务完成后,关闭此新进程与客户的通信链路,并终止

(4)返回第二步,等待另一个客户请求

(5)关闭服务器

客户方:

(1)打开一个通信通道,并连接到服务器所在的主机特定的端口

(2)向服务器发送请求,等待并接收应答,继续提出请求

(3)请求结束后关闭通信信道并终止

具体实现,新建服务端socket_server_tcp.c

具体代码如下: socket_server_tcp.c

// // Created by android on 19-8-9. // #include <stdio.h> #include <string.h> #include <arpa/inet.h> #include <sys/types.h> #include <sys/socket.h> #include <netinet/in.h> #include <netinet/ip.h> #define PORT 3040 //端口号 #define BACKLOG 5 //最大监听数 int main() { int iSocketFD = 0; //socket句柄 int iRecvLen = 0; //接收成功后的返回值 int new_fd = 0; //建立连接后的句柄 char buf[4096] = {0}; // struct sockaddr_in stLocalAddr = {0}; //本地地址信息结构图,下面有具体的属性赋值 struct sockaddr_in stRemoteAddr = {0}; //对方地址信息 socklen_t socklen = 0; iSocketFD = socket(AF_INET, SOCK_STREAM, 0); //建立socket SOCK_STREAM代表以tcp方式进行连接 if (0 > iSocketFD) { printf("创建socket失败!\n"); return 0; } stLocalAddr.sin_family = AF_INET; /*该属性表示接收本机或其他机器传输*/ stLocalAddr.sin_port = htons(PORT); /*端口号*/ stLocalAddr.sin_addr.s_addr = htonl(INADDR_ANY); /*IP,括号内容表示本机IP*/ //绑定地址结构体和socket if (0 > bind(iSocketFD, (void *) &stLocalAddr, sizeof(stLocalAddr))) { printf("绑定失败!\n"); return 0; } //开启监听 ,第二个参数是最大监听数 if (0 > listen(iSocketFD, BACKLOG)) { printf("监听失败!\n"); return 0; } printf("iSocketFD: %d\n", iSocketFD); //在这里阻塞知道接收到消息,参数分别是socket句柄,接收到的地址信息以及大小 new_fd = accept(iSocketFD, (void *) &stRemoteAddr, &socklen); if (0 > new_fd) { printf("接收失败!\n"); return 0; } else { printf("接收成功!\n"); //发送内容,参数分别是连接句柄,内容,大小,其他信息(设为0即可) send(new_fd, "这是服务器接收成功后发回的信息!", sizeof("这是服务器接收成功后发回的信息!"), 0); } printf("new_fd: %d\n", new_fd); iRecvLen = recv(new_fd, buf, sizeof(buf), 0); if (0 >= iRecvLen) //对端关闭连接 返回0 { printf("对端关闭连接或者接收失败!\n"); } else { printf("buf: %s\n", buf); } close(new_fd); close(iSocketFD); return 0; }

新建客户端端socket_client_tcp.c socket_client_tcp.c

// // Created by android on 19-8-9. // #include <stdio.h> #include <string.h> #include <arpa/inet.h> #include <sys/types.h> #include <sys/socket.h> #include <netinet/in.h> #include <netinet/ip.h> #define PORT 3040 //目标地址端口号 #define ADDR "10.6.191.177" //目标地址IP int main() { int iSocketFD = 0; //socket句柄 unsigned int iRemoteAddr = 0; struct sockaddr_in stRemoteAddr = {0}; //对端,即目标地址信息 socklen_t socklen = 0; char buf[4096] = {0}; //存储接收到的数据 iSocketFD = socket(AF_INET, SOCK_STREAM, 0); //建立socket if (0 > iSocketFD) { printf("创建socket失败!\n"); return 0; } stRemoteAddr.sin_family = AF_INET; stRemoteAddr.sin_port = htons(PORT); inet_pton(AF_INET, ADDR, &iRemoteAddr); stRemoteAddr.sin_addr.s_addr = iRemoteAddr; //连接方法: 传入句柄,目标地址,和大小 if (0 > connect(iSocketFD, (void *) &stRemoteAddr, sizeof(stRemoteAddr))) { printf("连接失败!\n"); //printf("connect failed:%d",errno);//失败时也可打印errno } else { printf("连接成功!\n"); recv(iSocketFD, buf, sizeof(buf), 0); ////将接收数据打入buf,参数分别是句柄,储存处,最大长度,其他信息(设为0即可)。 printf("Received:%s\n", buf); } close(iSocketFD);//关闭socket return 0; }

下面是我的编译及运行效果:

socket和http区别,websocket和socket区别(14)

编译命令如下:

gcc -o server socket_server_tcp.c gcc -o client socket_client_tcp.c #运行命令 ./server  #首先启动 ./client #次之启动基于UDP协议实现CS端

**基于UDP(面向无连接)的socket编程——**数据报式套接字(SOCK_DGRAM) 网络间通信AF_INET,典型的TCP/IP四型模型的通信过程

服务器:(多线程的【每10秒会打印一行#号】 与 循环监听) socket_server_udp.c

// // Created by android on 19-8-9. // #include <stdio.h> #include <sys/types.h> #include <sys/socket.h> #include <netinet/in.h> #include <netinet/ip.h> #include <pthread.h> void * test(void *pvData) { while(1) { sleep(5); printf("################################\n"); } return NULL; } int main(void) { pthread_t stPid = 0; int iRecvLen = 0; int iSocketFD = 0; char acBuf[4096] = {0}; struct sockaddr_in stLocalAddr = {0}; struct sockaddr_in stRemoteAddr = {0}; socklen_t iRemoteAddrLen = 0; /* 创建socket */ iSocketFD = socket(AF_INET, SOCK_DGRAM, 0); if(iSocketFD < 0) { printf("创建socket失败!\n"); return 0; } /* 填写地址 */ stLocalAddr.sin_family = AF_INET; stLocalAddr.sin_port = htons(12345); stLocalAddr.sin_addr.s_addr = 0; /* 绑定地址 */ if(0 > bind(iSocketFD, (void *)&stLocalAddr, sizeof(stLocalAddr))) { printf("绑定地址失败!\n"); close(iSocketFD); return 0; } pthread_create(&stPid, NULL, test, NULL); //实现了多线程 while(1) //实现了循环监听 { iRecvLen = recvfrom(iSocketFD, acBuf, sizeof(acBuf), 0, (void *)&stRemoteAddr, &iRemoteAddrLen); printf("iRecvLen: %d\n", iRecvLen); printf("acBuf:%s\n", acBuf); } close(iSocketFD); return 0; }

客户端: socket_client_udp.c

// // Created by android on 19-8-9. // #include <stdio.h> #include <string.h> #include <sys/types.h> #include <sys/socket.h> #include <netinet/in.h> #include <netinet/ip.h> #include <arpa/inet.h> int main(void) { int iRecvLen = 0; int iSocketFD = 0; int iRemotAddr = 0; char acBuf[4096] = {0}; struct sockaddr_in stLocalAddr = {0}; struct sockaddr_in stRemoteAddr = {0}; socklen_t iRemoteAddrLen = 0; /* 创建socket */ iSocketFD = socket(AF_INET, SOCK_DGRAM, 0); if(iSocketFD < 0) { printf("创建socket失败!\n"); return 0; } /* 填写服务端地址 */ stLocalAddr.sin_family = AF_INET; stLocalAddr.sin_port = htons(12345); inet_pton(AF_INET, "10.6.191.177", (void *)&iRemotAddr); stLocalAddr.sin_addr.s_addr = iRemotAddr; iRecvLen = sendto(iSocketFD, "这是一个测试字符串", strlen("这是一个测试字符串"), 0, (void *)&stLocalAddr, sizeof(stLocalAddr)); close(iSocketFD); return 0; }

测试:

1、编译服务器:因为有多线程,所以服务器端进程要进行pthread编译

gcc socket_server_udp.c -pthread -g -o server_udp #客户端和上方相同 复制代码

执行结果如下:

右下为客户端重复执行

socket和http区别,websocket和socket区别(15)

服务器端有主线程和辅线程,主线程,打印客户端发送的请求;辅线程每隔5秒钟打印一排#号。

,
上一页1234末页

栏目热文

文档排行

本站推荐

Copyright © 2018 - 2021 www.yd166.com., All Rights Reserved.