日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

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

發(fā)布時間:2025/3/15 编程问答 11 豆豆
生活随笔 收集整理的這篇文章主要介紹了 基于socket网络编程技术实现TCP和UDP的流程详解及实例 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

具體函數(shù)講解太多,根據(jù)程序自行分析。

可以參考這篇文章:

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系統(tǒng)使用socket過程

二、基于socket的TCP通信

2.1 基于socket技術(shù)的TCP通信流程

2.2 基于socket技術(shù)的TCP通信流程框圖

2.3 TCP socket編程實例

2.3.1 服務(wù)端(service.c)

2.3.2 客戶端(client.c)

三、基于socket的UDP通信

3.1? 基于socket技術(shù)的UDP通信流程框圖

3.2? 基于socket技術(shù)的UDP通信流程

3.2.1 服務(wù)器流程主要分為下述6個部分。

3.2.2 UDP協(xié)議的客戶端流程

3.3 UDPSocket客戶服務(wù)器通信實例

3.3.1 服務(wù)端(service.c)

3.3.2 客戶端(client.c)

3.4 UDP編程注意:


一、socket

1.1 socket概述

socket是在應(yīng)用層和傳輸層之間的一個抽象層,它把TCP/IP層復(fù)雜的操作抽象為幾個簡單的接口供應(yīng)用層調(diào)用已實現(xiàn)進(jìn)程在網(wǎng)絡(luò)中通信。

socket起源于UNIX,在Unix一切皆文件哲學(xué)的思想下,socket是一種"打開—讀/寫—關(guān)閉"模式的實現(xiàn),服務(wù)器和客戶端各自維護(hù)一個"文件",在建立連接打開后,可以向自己文件寫入內(nèi)容供對方讀取或者讀取對方內(nèi)容,通訊結(jié)束時關(guān)閉文件。

1.2 socket接口簡介

socket():創(chuàng)建socket

bind():綁定socket到本地地址和端口,通常由服務(wù)端調(diào)用

listen():TCP專用,開啟監(jiān)聽模式

accept():TCP專用,服務(wù)器等待客戶端連接,一般是阻塞態(tài)

connect():TCP專用,客戶端主動連接服務(wù)器

send():TCP專用,發(fā)送數(shù)據(jù)

recv():TCP專用,接收數(shù)據(jù)

sendto():UDP專用,發(fā)送數(shù)據(jù)到指定的IP地址和端口

recvfrom():UDP專用,接收數(shù)據(jù),返回數(shù)據(jù)遠(yuǎn)端的IP地址和端口

close():關(guān)閉socket

1.3 Linux系統(tǒng)使用socket過程

在Linux下進(jìn)行程序運行的方法:(假設(shè)已經(jīng)編寫好服務(wù)端程序(service.c),和客戶端程序(client.c))

(需要開啟兩個終端)

1. 先分別對兩個文件進(jìn)行編譯(分別執(zhí)行以下兩條命令)

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

2. 然后先運行服務(wù)器端

./service

3.? 再在另一個終端中運行客戶端

./client

4. 執(zhí)行完成!

二、基于socket的TCP通信

2.1 基于socket技術(shù)的TCP通信流程

服務(wù)端(被動連接,需創(chuàng)建自己的地址信息)

創(chuàng)建一個套接字 ———socket()
綁定IP地址、端口等信息到socket上——bind()
監(jiān)聽套接字——listen()
等待客戶端的連接請求——accept()
發(fā)送、接收數(shù)據(jù)——send()和recv(),或者read()和write()
關(guān)閉網(wǎng)絡(luò)連接——close()

客戶端

創(chuàng)建一個套接字——socket()
連接服務(wù)器——connect()
接收、發(fā)送數(shù)據(jù)——send()和recv(),或者read()和write()
關(guān)閉網(wǎng)絡(luò)連接——close()

2.2 基于socket技術(shù)的TCP通信流程框圖

2.3 TCP socket編程實例

2.3.1 服務(wù)端(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(){//創(chuàng)建套接字int serv_sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);//將套接字和IP、端口綁定struct sockaddr_in serv_addr;memset(&serv_addr, 0, sizeof(serv_addr)); //每個字節(jié)都用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));//進(jìn)入監(jiān)聽狀態(tài),等待用戶發(fā)起請求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);//向客戶端發(fā)送數(shù)據(jù)char str[] = "Hello World!";write(clnt_sock, str, sizeof(str));//關(guān)閉套接字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(){//創(chuàng)建套接字int sock = socket(AF_INET, SOCK_STREAM, 0);//向服務(wù)器(特定的IP和端口)發(fā)起請求struct sockaddr_in serv_addr;memset(&serv_addr, 0, sizeof(serv_addr)); //每個字節(jié)都用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));//讀取服務(wù)器傳回的數(shù)據(jù)char buffer[40];read(sock, buffer, sizeof(buffer)-1);printf("Message form server: %s\n", buffer);//關(guān)閉套接字close(sock);return 0; }

三、基于socket的UDP通信

3.1? 基于socket技術(shù)的UDP通信流程框圖

UDP協(xié)議的程序設(shè)計框架,客戶端和服務(wù)器之間的差別在于服務(wù)器必須使用bind()函數(shù)來綁定偵聽的本地UDP端口,而客戶端則可以不進(jìn)行綁定,直接發(fā)送到服務(wù)器地址的某個端口地址。框圖如圖所示。

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

3.2? 基于socket技術(shù)的UDP通信流程

3.2.1 服務(wù)器流程主要分為下述6個部分。

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

(2)設(shè)置服務(wù)器IP地址和端口,初始化要綁定的網(wǎng)絡(luò)地址結(jié)構(gòu)。

(3)綁定IP地址、端口等信息,使用bind()函數(shù),將套接字文件描述符和一個地址進(jìn)行綁定。

(4)循環(huán)接收客戶端的數(shù)據(jù),使用recvfrom()函數(shù)接收客戶端的網(wǎng)絡(luò)數(shù)據(jù)。

(5)向客戶端發(fā)送數(shù)據(jù),使用sendto()函數(shù)向服務(wù)器主機(jī)發(fā)送數(shù)據(jù)。

(6)關(guān)閉套接字,使用close()函數(shù)釋放資源。UDP協(xié)議的客戶端流程

3.2.2 UDP協(xié)議的客戶端流程

UDP協(xié)議的客戶端流程分為5個部分。

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

(2)設(shè)置服務(wù)器IP地址和端口,struct sockaddr;

(3)向服務(wù)器發(fā)送數(shù)據(jù),sendto();

(4)接收服務(wù)器的數(shù)據(jù),recvfrom();

(5)關(guān)閉套接字,close()。

3.3 UDPSocket客戶服務(wù)器通信實例

3.3.1 服務(wù)端(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;//服務(wù)器和客戶端地址sock_fd = socket(AF_INET,SOCK_DGRAM,0);if(sock_fd < 0){perror("socket");exit(1);} else{printf("sock sucessful\n");}//初始化服務(wù)器斷地址memset(&addr_serv,0,sizeof(struct sockaddr_in));addr_serv.sin_family = AF_INET;//協(xié)議族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;/*服務(wù)端地址,客戶端地址*/sock_fd = socket(AF_INET,SOCK_DGRAM,0);//創(chuàng)建套接子//初始化服務(wù)器端地址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報文可能會丟失、重復(fù)

2、UDP報文可能會亂序

3、UDP缺乏流量控制

4、UDP協(xié)議數(shù)據(jù)報文截斷

5、recvfrom返回0,不代表連接關(guān)閉,因為udp是無連接的。

6、ICMP異步錯誤

7、UDP connect

8、UDP外出接口的確定

9、太大的UDP包可能出現(xiàn)的問題

參考鏈接:

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

與50位技術(shù)專家面對面20年技術(shù)見證,附贈技術(shù)全景圖

總結(jié)

以上是生活随笔為你收集整理的基于socket网络编程技术实现TCP和UDP的流程详解及实例的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。