具体函数讲解太多,根据程序自行分析。

可以参考这篇文章:

https://blog.csdn.net/qq_41687938/article/details/119102328?spm=1001.2014.3001.5501

https://blog.csdn.net/weixin_42193813/article/details/105666316

目录

一、socket

1.1 socket概述

1.2 socket接口简介

1.3 Linux系统使用socket过程

二、基于socket的TCP通信

2.1 基于socket技术的TCP通信流程

2.2 基于socket技术的TCP通信流程框图

2.3 TCP socket编程实例

2.3.1 服务端(service.c)

2.3.2 客户端(client.c)

三、基于socket的UDP通信

3.1  基于socket技术的UDP通信流程框图

3.2  基于socket技术的UDP通信流程

3.2.1 服务器流程主要分为下述6个部分。

3.2.2 UDP协议的客户端流程

3.3 UDPSocket客户服务器通信实例

3.3.1 服务端(service.c)

3.3.2 客户端(client.c)

3.4 UDP编程注意:


一、socket

1.1 socket概述

socket是在应用层和传输层之间的一个抽象层,它把TCP/IP层复杂的操作抽象为几个简单的接口供应用层调用已实现进程在网络中通信。

socket起源于UNIX,在Unix一切皆文件哲学的思想下,socket是一种"打开—读/写—关闭"模式的实现,服务器和客户端各自维护一个"文件",在建立连接打开后,可以向自己文件写入内容供对方读取或者读取对方内容,通讯结束时关闭文件。

1.2 socket接口简介

socket():创建socket

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

listen():TCP专用,开启监听模式

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

connect():TCP专用,客户端主动连接服务器

send():TCP专用,发送数据

recv():TCP专用,接收数据

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

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

close():关闭socket

1.3 Linux系统使用socket过程

在Linux下进行程序运行的方法:(假设已经编写好服务端程序(service.c),和客户端程序(client.c))

(需要开启两个终端)

1. 先分别对两个文件进行编译(分别执行以下两条命令)

gcc service.c -o service
gcc client.c -o client

2. 然后先运行服务器端

./service

3.  再在另一个终端中运行客户端

./client

4. 执行完成!

二、基于socket的TCP通信

2.1 基于socket技术的TCP通信流程

服务端(被动连接,需创建自己的地址信息)

创建一个套接字 ———socket()
绑定IP地址、端口等信息到socket上——bind()
监听套接字——listen()
等待客户端的连接请求——accept()
发送、接收数据——send()和recv(),或者read()和write()
关闭网络连接——close()

客户端

创建一个套接字——socket()
连接服务器——connect()
接收、发送数据——send()和recv(),或者read()和write()
关闭网络连接——close()

2.2 基于socket技术的TCP通信流程框图

2.3 TCP socket编程实例

2.3.1 服务端(service.c)

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <arpa/inet.h>
#include <sys/socket.h>
#include <netinet/in.h>
int main(){//创建套接字int serv_sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);//将套接字和IP、端口绑定struct sockaddr_in serv_addr;memset(&serv_addr, 0, sizeof(serv_addr));  //每个字节都用0填充serv_addr.sin_family = AF_INET;  //使用IPv4地址serv_addr.sin_addr.s_addr = inet_addr("127.0.0.1");  //具体的IP地址serv_addr.sin_port = htons(1258);  //端口bind(serv_sock, (struct sockaddr*)&serv_addr, sizeof(serv_addr));//进入监听状态,等待用户发起请求listen(serv_sock, 20);//接收客户端请求struct sockaddr_in clnt_addr;socklen_t clnt_addr_size = sizeof(clnt_addr);int clnt_sock = accept(serv_sock, (struct sockaddr*)&clnt_addr, &clnt_addr_size);//向客户端发送数据char str[] = "Hello World!";write(clnt_sock, str, sizeof(str));//关闭套接字close(clnt_sock);close(serv_sock);return 0;
}

2.3.2 客户端(client.c)

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <arpa/inet.h>
#include <sys/socket.h>
int main(){//创建套接字int sock = socket(AF_INET, SOCK_STREAM, 0);//向服务器(特定的IP和端口)发起请求struct sockaddr_in serv_addr;memset(&serv_addr, 0, sizeof(serv_addr));  //每个字节都用0填充serv_addr.sin_family = AF_INET;  //使用IPv4地址serv_addr.sin_addr.s_addr = inet_addr("127.0.0.1");  //具体的IP地址serv_addr.sin_port = htons(1258);  //端口connect(sock, (struct sockaddr*)&serv_addr, sizeof(serv_addr));//读取服务器传回的数据char buffer[40];read(sock, buffer, sizeof(buffer)-1);printf("Message form server: %s\n", buffer);//关闭套接字close(sock);return 0;
}

三、基于socket的UDP通信

3.1  基于socket技术的UDP通信流程框图

UDP协议的程序设计框架,客户端和服务器之间的差别在于服务器必须使用bind()函数来绑定侦听的本地UDP端口,而客户端则可以不进行绑定,直接发送到服务器地址的某个端口地址。框图如图所示。

基于socket的UDP通信流程示意图

3.2  基于socket技术的UDP通信流程

3.2.1 服务器流程主要分为下述6个部分。

(1)建立套接字文件描述符,使用函数socket(),生成套接字文件描述符。

(2)设置服务器IP地址和端口,初始化要绑定的网络地址结构。

(3)绑定IP地址、端口等信息,使用bind()函数,将套接字文件描述符和一个地址进行绑定。

(4)循环接收客户端的数据,使用recvfrom()函数接收客户端的网络数据。

(5)向客户端发送数据,使用sendto()函数向服务器主机发送数据。

(6)关闭套接字,使用close()函数释放资源。UDP协议的客户端流程

3.2.2 UDP协议的客户端流程

UDP协议的客户端流程分为5个部分。

(1)建立套接字文件描述符,socket();

(2)设置服务器IP地址和端口,struct sockaddr;

(3)向服务器发送数据,sendto();

(4)接收服务器的数据,recvfrom();

(5)关闭套接字,close()。

3.3 UDPSocket客户服务器通信实例

3.3.1 服务端(service.c)

#include<stdio.h>
#include<sys/types.h>
#include<sys/socket.h>
#include<netinet/in.h>
#include<unistd.h>
#include<errno.h>
#include<string.h>
#include<stdlib.h>#define SERV_PORT 3000int main()
{int sock_fd; //套接子描述符号int recv_num;int send_num;int client_len;char recv_buf[20];struct sockaddr_in addr_serv;struct sockaddr_in addr_client;//服务器和客户端地址sock_fd = socket(AF_INET,SOCK_DGRAM,0);if(sock_fd < 0){perror("socket");exit(1);} else{printf("sock sucessful\n");}//初始化服务器断地址memset(&addr_serv,0,sizeof(struct sockaddr_in));addr_serv.sin_family = AF_INET;//协议族addr_serv.sin_port = htons(SERV_PORT);addr_serv.sin_addr.s_addr = htonl(INADDR_ANY);//任意本地址client_len = sizeof(struct sockaddr_in);/*绑定套接子*/if(bind(sock_fd,(struct sockaddr *)&addr_serv,sizeof(struct sockaddr_in))<0 ){perror("bind");exit(1);} else{    printf("bind sucess\n");}while(1){printf("begin recv:\n");recv_num = recvfrom(sock_fd,recv_buf,sizeof(recv_buf),0,(struct sockaddr *)&addr_client,&client_len);if(recv_num < 0){printf("bad\n");perror("again recvfrom");exit(1);} else{recv_buf[recv_num]='\0';printf("recv sucess:%s\n",recv_buf);}printf("begin send:\n");send_num = sendto(sock_fd,recv_buf,recv_num,0,(struct sockaddr *)&addr_client,client_len);if(send_num < 0){perror("sendto");exit(1);} else{printf("send sucessful\n");}}close(sock_fd);return 0;
}

3.3.2 客户端(client.c)

#include<stdio.h>
#include<string.h>
#include<errno.h>
#include<stdlib.h>
#include<unistd.h>#include<sys/types.h>
#include<sys/socket.h>
#include<netinet/in.h>#define DEST_PORT 3000
#define DSET_IP_ADDRESS "192.168.1.103"int main()
{int sock_fd;/*套接字文件描述符*/int send_num;int recv_num;int dest_len;char send_buf[20]={"hello tiger"};char recv_buf[20];struct sockaddr_in addr_serv;/*服务端地址,客户端地址*/sock_fd = socket(AF_INET,SOCK_DGRAM,0);//创建套接子//初始化服务器端地址memset(&addr_serv,0,sizeof(addr_serv));addr_serv.sin_family = AF_INET;addr_serv.sin_addr.s_addr = inet_addr(DSET_IP_ADDRESS);addr_serv.sin_port = htons(DEST_PORT);dest_len = sizeof(struct sockaddr_in);printf("begin send:\n");send_num = sendto(sock_fd,send_buf,sizeof(send_buf),0,(struct sockaddr *)&addr_serv,dest_len);if(send_num < 0){perror("sendto");exit(1);} else{printf("send sucessful:%s\n",send_buf);}recv_num = recvfrom(sock_fd,recv_buf,sizeof(recv_buf),0,(struct sockaddr *)&addr_serv,&dest_len);if(recv_num <0 ){perror("recv_from");exit(1);} else{printf("recv sucessful\n");}recv_buf[recv_num]='\0';printf("the receive:%s\n",recv_buf);close(sock_fd);return 0;
}

3.4 UDP编程注意:

1、UDP报文可能会丢失、重复

2、UDP报文可能会乱序

3、UDP缺乏流量控制

4、UDP协议数据报文截断

5、recvfrom返回0,不代表连接关闭,因为udp是无连接的。

6、ICMP异步错误

7、UDP connect

8、UDP外出接口的确定

9、太大的UDP包可能出现的问题

参考链接:

https://blog.csdn.net/lell3538/article/details/53335472

https://blog.csdn.net/dongyanxia1000/article/details/80743691

https://blog.csdn.net/weixin_42193813/article/details/105771978

基于socket网络编程技术实现TCP和UDP的流程详解及实例相关推荐

  1. 【Socket网络编程】4.tcp和udp的客户端和服务端收发流程

    tcp和udp的客户端和服务端收发流程 1.udp服务器流程: 1.创建serverSocket 2.设置服务器地址 serverAddr 3.将serverSocket和serverAddr绑定 b ...

  2. 高等学校计算机科学与技术教材:tcp/ip网络编程技术基础,TCP/IP网络编程技术基础...

    TCP/IP网络编程技术基础 语音 编辑 锁定 讨论 上传视频 <TCP/IP网络编程技术基础>是2012年北京交通大学出版社出版的图书,作者是王雷. 书    名 TCP/IP网络编程技 ...

  3. tcp udp区别优缺点_Linux网络编程面试题--tcp和udp的区别

    (1)TCP是基于连接的,UDP是基于无连接的. (2)TCP的数据是可靠的,UDP的数据是不可靠的. (3)TCP的数据是有序的,UDP的数据是无序的. (4)TCP不保存用户边界,UDP保存用户边 ...

  4. 【Linux网络编程】TCP 和 UDP 数据报格式详解

    TCP 报文格式 TCP(Transmission Control Protocol 传输控制协议)是一种面向连接的.可靠的.基于字节流的传输层通信协议. TCP 报文段的报头有 10 个必需的字段和 ...

  5. php socket keepalive,【 总结 】Tcp Keepalive 和 HTTP Keepalive 详解

    TCP Keepalive Tcp keepalive的起源双方建立交互的连接,但是并不是一直存在数据交互,有些连接会在数据交互完毕后,主动释放连接,而有些不会,那么在长时间无数据交互的时间段内, 交 ...

  6. 传输层协议TCP和UDP的区别详解

    一.TCP协议 1.TCP的优点: 可靠,稳定 TCP的可靠体现在TCP在传递数据之前,会有三次握手来建立连接,而且在数据传递时,有确认.窗口.重传.拥塞控制机制,在数据传完后,还会断开连接用来节约系 ...

  7. uip tcp udp运行流程详解

    uip_process运行流程 uip_process(u8_t flag) (1)if(flag == UIP_UDP_SEND_CONN),若是则goto udp_send;不是则向下执行: (2 ...

  8. 糖儿飞教你学C++ Socket网络编程——5.2 TCP通信程序的函数及流程总结

    TCP服务器端程序流程 监听套接字=socket(AF_INET, 套接字的类型, 0) bind(监听套接字, 本地地址, 地址长度) 通信套接字=accept(监听套接字, 对方地址, 地址长度的 ...

  9. 网络编程2(TCP、UDP)

    多路复用 多路复用 select pselect poll epoll 多路复用 ​ 使用一个进程(且只有一个主线程)同时监控若干个socket文件描述符的读写,这种读写模式叫做多路复用 ​ 多用于T ...

最新文章

  1. 2023 USNews全美计算机研究生院排名发布!MIT、CMU分别称霸总榜和AI分榜
  2. what should you do if you want to have a high efficiency for communication
  3. C++二叉堆binary heap (附完整源码)
  4. asp.net core 系列之允许跨域访问2之测试跨域(Enable Cross-Origin Requests:CORS)
  5. SolarWinds 升级 APM Suite,简化应用程序和基础架构管理!
  6. CocosCreator物理引擎Demo源码分析(1)-infinite-world
  7. Android常用的 adb shell命令
  8. 计算机专业小米笔记本推荐,小米笔记本电脑怎么样有哪些型号,哪款性价比高?...
  9. Android UI自动化工具-SoloPi
  10. (莱昂氏unix源代码分析导读-19)再谈进程swtch
  11. echarts做中国地图分布
  12. Python3-标准库概览
  13. 实现按钮的长按监听(聂同学的作业)
  14. 单目标跟踪通过CAM绘制heatmap图像(以SiamCAR为例)
  15. Kali [Aquatone]子域名探测工具
  16. 聊天室加入用户名查重功能
  17. Cadence Allegro如何设置十字大光标?
  18. 代码工人还是程序员?
  19. android车载严格模式解除,Android严格模式
  20. Unity 游戏框架搭建 2019 (四十二) MonoBehaviour 简化

热门文章

  1. IEEE作者中心!解决你的选刊,模板,选题,写做的一系列困难!!!拿走不谢!!!
  2. ethz研究生申请官网
  3. UNIYT关于V S2017,VS2019断点调试卡住的问题
  4. 【转】C++ traits技术
  5. UNITY C#内存泄漏
  6. vc2010多线程使用std标准模板库容器DEBUG版迭代器BUG
  7. React ----- 路由懒加载的几种实现方案
  8. 一步一步理解Java 企业级应用的可扩展性
  9. Java 引用分类:StrongReference、SoftReference、WeakReference、PhantomReference
  10. Step by Step Setup Git Server on Windows with CopSSH + msysGit and Integrate Git with Visual Studio