欢迎来到尧图网

客户服务 关于我们

您的位置:首页 > 健康 > 养生 > 网络编程-TCP

网络编程-TCP

2024/10/25 20:18:42 来源:https://blog.csdn.net/LHB15173352347/article/details/142626264  浏览:    关键词:网络编程-TCP

网络通信基础

1、网络通信的协议:TCPUDPIP

2、网络通信模型:七层模型、四层模型

3、网络通信理论:socketIP、端口号、字节序

4、网络IO模型:4种

5、网络超时处理

6、网络的广播、组播、单播

网络通信的特征

(局域网)不同设备在通信时,要求其IP地址必须处于同一网段

网络通信协议
TCP\IP

(传输控制协议\因特网互联协议)

TCP:主要是数据发送数据时,若出现数据发送失败,可控制进行重新发送

IP:用于通信过程的IP地址

UDP

(用户数据报协议)

UDP:没有数据重发机制

TCPUDP
可靠通信不可靠通信
通信效率低通信效率高
面向连接面向非连接
网络通信模型
七层模型四层模型
应用层领导口述一段话
表示层秘书记录口述内容形成信件
会话层将信件放在公司前台应用层领导自己写信放置前台
传输层快递员从前台取件传输层快递员从前台取件
网络层分拣快递理清发送地址网络层分拣快递理清发送地址
数据链路层快递传输过程
物理层将信件送至收件人网络链路层投送快递到收件人
网络通信理论

socket:套接字,特殊的文件描述符,不允许使用open打开

IP:当前所用的IP地址都是32位的点分式,用于区分设备

端口号:2字节的短整型(1~65535)自己写的程序中端口号一般设置大于10000即可,用于区分应用

字节序:在x86体系下,操作系统一般是小端存储模式,对于网络通信一般是大端存储模式

网络通信高级

TCP通信流程
客户端服务器
保证有一台手机int cfd = socket保证有一台手机int sdf = socket
拨打号码connect(cfd)需要绑定一个手机号bind(sfd)
畅聊,相当于收发数据send(cfd)设定手机铃声,用于监视listen(sfd)
挂断电话close(cfd)等待来电,等待客户端连接请求int cfd = accept(sfd)
畅聊,相当于收发数据recv(cfd)
挂断电话close(cfd)close(sfd)
//实现一个客户端给服务器发送 服务器负责接收
//head.h
#ifndef _HEAD_H
#define _HEAD_H#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <strings.h>
#include <errno.h>
#include <fcntl.h>
#include <unistd.h>
#include <dirent.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/wait.h>
#include <signal.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <sys/msg.h>
#include <sys/sem.h>
#include <semaphore.h>
#include <pthread.h>
#include <sys/socket.h>
#include <arpa/inet.h>#endif 
//服务端
// ./server 1277.0.0.1 10001
int main(int argc, char* argv[])
{// 参数1:代表IPV4// 参数2:代表TCP// 参数3:默认为0,一般不用// 返回值:返回服务端的套接字,失败返回-1// 1、创建套接字int sfd = socket(AF_INET, SOCK_STREAM, 0);if(sfd < 0){perror("socket error");return -1;}// 知道创建操作完成printf("socket success\n");// 2、服务端绑定IP地址和端口号struct sockaddr_in addr;addr.sin_family = AF_INET;	// 地址族IPV4addr.sin_port = atoi(argv[2]);	// 设置端口号// 将字符串形式的IP地址直接转换成网络地址int ret = inet_pton(AF_INET, argv[1], (struct in_addr*)&addr.sin_addr);if(ret <= 0){perror("inet_pton error");return -1;}ret = bind(sfd, (struct sockaddr*)&addr, sizeof(addr));if(ret < 0){perror("bind error\n");return -1;}// 知道绑定操作完成printf("bind success\n");//3、实现监听操作ret = listen(sfd, 2);if(ret < 0){perror("listen error");return -1;}//知道监听完成printf("listen success\n");//4、等待客户端的连接请求struct sockaddr_in cld_addr;	//出参:待会连接客户端的IP端口号int len = sizeof(cld_addr);int cfd = accept(sfd, (struct sockaddr*)&cld_addr, &len);if(cfd < 0){perror("accept error");return -1;}//知道连接完成printf("accept success!\n");//5、接收客户端的数据char buf[100];while(1){bzero(buf, sizeof(buf));recv(cfd, buf, sizeof(buf)-1, 0);if(strstr(buf, "quit") != NULL){break;}printf("from %d info is:%s\n", cfd, buf);}//6、关闭套接字close(cfd);close(sfd);printf("server closed!\n");return 0;
}//客户端
// ./client 127.0.0.1 10001
int main(int argc, char* argv[])
{// 1、创建套接字int cfd = socket(AF_INET, SOCK_STREAM, 0);if(cfd < 0){perror("socket error");return -1;}// 知道创建操作完成printf("socket success\n");// 2、向服务端发送连接申请struct sockaddr_in addr;addr.sin_family = AF_INET;	// 地址族IPV4addr.sin_port = atoi(argv[2]);	// 设置端口号// 将字符串形式的IP地址直接转换成网络地址int ret = inet_pton(AF_INET, argv[1], (struct in_addr*)&addr.sin_addr);if(ret <= 0){perror("inet_pton error");return -1;}ret = connect(cfd, (struct sockaddr*)&addr, sizeof(addr));if(ret < 0){perror("connect error\n");return -1;}// 知道绑定操作完成printf("connect success\n");//3、向服务端的数据char buf[100];while(1){bzero(buf, sizeof(buf));fgets(buf, sizeof(buf), stdin);send(cfd, buf, sizeof(buf)-1, 0);if(strstr(buf, "quit") != NULL){break;}}close(cfd);printf("client closed!\n");return 0;
}
//实现多个客户端给服务端发送请求
//服务端
// ./server 1277.0.0.1 10001void* handle_client(void* arg)
{int cfd = *((int*)arg);/* 5、接收客户端的数据 */char buf[100];while(1){bzero(buf, sizeof(buf));recv(cfd, buf, sizeof(buf)-1, 0);if (strstr(buf, "quit") != NULL){printf("client [%d] is quit!\n", cfd);close(cfd);pthread_exit(NULL);}if (strlen(buf) != 0){printf("from %d info is: %s\n", cfd, buf);}}}// ./server 127.0.0.1 10001
int main(int argc,char *argv[])
{/* 1、创建套接字 */int sfd = socket(AF_INET, SOCK_STREAM, 0);if (sfd < 0){perror("socket error");return -1;}printf("socket success!\n");/* 2、服务端绑定IP地址和端口号 */struct sockaddr_in addr;addr.sin_family = AF_INET;      // 地址簇IPV4addr.sin_port = atoi(argv[2]);  // 设置端口号// 将字符串形式的IP地址,直接转换为网络地址int ret = inet_pton(AF_INET, argv[1], (struct in_addr*)&addr.sin_addr);if (ret <= 0){perror("inet_pton error");return -1;}ret = bind(sfd, (struct sockaddr *)&addr, sizeof(addr));if (ret < 0){perror("bind error!\n");return -1;}printf("bind success!\n");/* 3、实现监听操作 */ret = listen(sfd, 5);if (ret < 0){perror("listen error!\n");return -1;}printf("listen success!\n");/* 4、等待客户端的连接请求 */struct sockaddr_in cld_addr; // 出参: 带回连接客户端的IP和端口号int len = sizeof(cld_addr);// 主循环,接受客户端连接int cfd;pthread_t thread_id;while (1) {cfd = accept(sfd, (struct sockaddr *)&cld_addr, &len);if (cfd < 0){// 当前客户端请求失败后,只报错,不能退出程序// 因为其他进程还要进行连接。perror("accept error!\n");}else{// 连接请求成功后,在多线程中进行读写操作printf("client socket = [%d]: accept success!\n", cfd);if (pthread_create(&thread_id, NULL, handle_client, (void*)&cfd) != 0) {// 如果线程创建失败表明无法与客户端实现数据通信,则将客户端的套接字关闭。printf("client socket = [%d]: could not create thread: %s\n", cfd, strerror(errno));close(cfd);}}// 分离线程,让线程自主运行pthread_detach(thread_id);}/* 6、关闭套接字 */// 这个一般执行不到,因为服务端需要一值运行close(cfd);close(sfd);printf("server closed!\n");return 0;
}

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com