欢迎访问 生活随笔!

生活随笔

当前位置: 首页 >

计算机网络:TCP

发布时间:2025/6/15 41 豆豆
生活随笔 收集整理的这篇文章主要介绍了 计算机网络:TCP 小编觉得挺不错的,现在分享给大家,帮大家做个参考.

TCP与UDP的比较 

 

 创建tcp套接字

#include<stdio.h> #include<stdlib.h> #include<sys/types.h> #include<sys/socket.h>int main(int argc, char const * argv[]){int sockfd;// 创建tcp套接字if((sockfd=socket(AF_INET,SOCK_STREAM,0)) == -1){perror("fail to socket");exit(1);}printf("sockfd=%d\n", sockfd);return 0; }

 tcp客户端

#include<stdlib.h> #include<stdio.h> #include<string.h> #include<sys/types.h> #include<sys/socket.h> #include<arpa/inet.h> #include<netinet/in.h> #include<unistd.h>#define N 128 int main(int argc, char const * argv[]){if(argc < 3){fprintf(stderr, "Usage:%s ip port\n",argv[0]);exit(1);}int sockfd;// 创建tcp套接字if((sockfd=socket(AF_INET,SOCK_STREAM,0)) == -1){perror("fail to socket");exit(1);}struct sockaddr_in serveraddr;socklen_t addrlen = sizeof(serveraddr);serveraddr.sin_family = AF_INET; // 协议族 AF_INET:ipv4网络协议// inet_addr: 将点分十进制字符串ip地址转为整形数据serveraddr.sin_addr.s_addr = inet_addr(argv[1]); // ip地址// atoi 将数字型字符串转换为整形数据// htons 将主机字节序转化为网络字节序serveraddr.sin_port = htons(atoi(argv[2]));// 主动跟服务器建立链接if(connect(sockfd,(struct sockaddr*)&serveraddr, addrlen) == -1){perror("fail to connect");exit(1);};char buf[N] = "";while(1){// 读取终端输入的数据到buf中fgets(buf,N,stdin);//发送buf数据if(send(sockfd,buf,sizeof(buf),0)==-1){perror("fail to send");exit(1);}}printf("sockfd=%d\n", sockfd);return 0; }

 使用网络调试助手作为tcp服务器

 

 

 tcp服务器(tcp原本不是并发服务器,同一时间只能与一个客户端通信)

   tcp不能并发的原因: 由于服务器端有两个阻塞函数,accept和recv,两个函数需要先后运行。所以导致运行一个函数的时候,另一个函数无法执行。无法保证一边连接客户端,一边与其他客户端通信。

#include<stdlib.h> #include<stdio.h> #include<string.h> #include<sys/types.h> #include<sys/socket.h> #include<arpa/inet.h> #include<netinet/in.h> #include<unistd.h>#define N 128 int main(int argc, char const * argv[]){if(argc < 3){fprintf(stderr, "server Usage:%s ip port\n",argv[0]);exit(1);}int sockfd;// 创建tcp套接字if((sockfd=socket(AF_INET,SOCK_STREAM,0)) == -1){perror("fail to socket");exit(1);}struct sockaddr_in serveraddr;socklen_t addrlen = sizeof(serveraddr); serveraddr.sin_family = AF_INET; // 协议族 AF_INET:ipv4网络协议// inet_addr: 将点分十进制字符串ip地址转为整形数据serveraddr.sin_addr.s_addr = inet_addr(argv[1]); // ip地址// atoi 将数字型字符串转换为整形数据// htons 将主机字节序转化为网络字节序serveraddr.sin_port = htons(atoi(argv[2]));// 将套接字和网络信息绑定if(bind(sockfd,(struct sockaddr*)&serveraddr, addrlen) == -1){perror("fail to connect");exit(1);};// 将套接字设置为监听状态if(listen(sockfd,5) == -1){perror("fail to listen");exit(1);}struct sockaddr_in clientsock;addrlen = sizeof(clientsock);char buf[N] = "666";char text[N] = "";printf("准备阻塞...\n");// 阻塞等待客户端的链接int clisock = accept(sockfd,(struct sockaddr*)&clientsock, &addrlen);int count = 0;while(1){ // 打印客户端信息printf("ip:%s, port:%d\n", inet_ntoa(clientsock.sin_addr), ntohs(clientsock.sin_port));// 接收数据if((count = recv(clisock,text,N,0))==-1){perror("fail to recv");exit(1);}printf("from client: ");for(int j=0;j<count;j++){printf("%c",text[j]);}printf("\n");//发送buf数据if(send(clisock,buf,sizeof(buf),0)==-1){perror("fail to send");exit(1);}}// 关闭套接字描述符close(clisock);close(sockfd);return 0; }

 

 

 

多进程实现tcp并发服务器

#include<stdlib.h> #include<stdio.h> #include<string.h> #include<sys/types.h> #include<sys/socket.h> #include<arpa/inet.h> #include<netinet/in.h> #include<unistd.h> #include <signal.h> #include <sys/wait.h>#define N 128void handler(int sig){wait(NULL); }int main(int argc, char const * argv[]){if(argc < 3){fprintf(stderr, "server Usage:%s ip port\n",argv[0]);exit(1);}int sockfd;// 创建tcp套接字if((sockfd=socket(AF_INET,SOCK_STREAM,0)) == -1){perror("fail to socket");exit(1);}struct sockaddr_in serveraddr;socklen_t addrlen = sizeof(serveraddr); serveraddr.sin_family = AF_INET; // 协议族 AF_INET:ipv4网络协议// inet_addr: 将点分十进制字符串ip地址转为整形数据serveraddr.sin_addr.s_addr = inet_addr(argv[1]); // ip地址// atoi 将数字型字符串转换为整形数据// htons 将主机字节序转化为网络字节序serveraddr.sin_port = htons(atoi(argv[2]));// 将套接字和网络信息绑定if(bind(sockfd,(struct sockaddr*)&serveraddr, addrlen) == -1){perror("fail to connect");exit(1);};// 将套接字设置为监听状态if(listen(sockfd,5) == -1){perror("fail to listen");exit(1);}struct sockaddr_in clientsock;addrlen = sizeof(clientsock);char buf[N] = "666";char text[N] = "";printf("准备阻塞...\n");// 使用信号,异步的方式处理僵尸进程signal(SIGCHLD,handler);while(1){ // 阻塞等待客户端的链接int clisock = accept(sockfd,(struct sockaddr*)&clientsock, &addrlen);int pid = fork();int count = 0;if(pid > 0){ // 父进程负责执行accept函数,所以if语句结束后,继续在accept函数的位置阻塞}else if(pid == 0){ // 子进程负责跟指定的客户端通信while(1){// 打印客户端信息printf("ip:%s, port:%d\n", inet_ntoa(clientsock.sin_addr), ntohs(clientsock.sin_port));// 接收数据if((count = recv(clisock,text,N,0))==-1){perror("fail to recv");exit(1);}else if(count == 0){printf("The client quited\n");exit(0);}printf("from client: ");for(int j=0;j<count;j++){printf("%c",text[j]);}printf("\n");//发送buf数据if(send(clisock,buf,sizeof(buf),0)==-1){perror("fail to send");exit(1);}}}}// 关闭套接字描述符//close(clisock);//close(sockfd);return 0; }

 

多线实现tcp并发服务器 

#include<stdlib.h> #include<stdio.h> #include<string.h> #include<sys/types.h> #include<sys/socket.h> #include<arpa/inet.h> #include<netinet/in.h> #include<unistd.h> #include <signal.h> #include <sys/wait.h> #include <pthread.h>#define N 128void handler(int sig){wait(NULL); }typedef struct{struct sockaddr_in addr;int acceptfd; }MSG;void *pthread_fun(void *arg){int count = 0;ssize_t bytes;MSG msg = *(MSG *)arg; char buf[N] = "666";char text[N] = "";while(1){// 打印客户端信息printf("ip:%s, port:%d\n", inet_ntoa(msg.addr.sin_addr), ntohs(msg.addr.sin_port));// 接收数据if((count = recv(msg.acceptfd,text,N,0))==-1){perror("fail to recv");exit(1);}else if(count == 0){printf("The client quited\n");pthread_exit(NULL);}printf("from client: ");for(int j=0;j<count;j++){printf("%c",text[j]);}printf("\n");//发送buf数据if(send(msg.acceptfd,buf,sizeof(buf),0)==-1){perror("fail to send");exit(1);}} }int main(int argc, char const * argv[]){if(argc < 3){fprintf(stderr, "server Usage:%s ip port\n",argv[0]);exit(1);}int sockfd;// 创建tcp套接字if((sockfd=socket(AF_INET,SOCK_STREAM,0)) == -1){perror("fail to socket");exit(1);}struct sockaddr_in serveraddr;socklen_t addrlen = sizeof(serveraddr); serveraddr.sin_family = AF_INET; // 协议族 AF_INET:ipv4网络协议// inet_addr: 将点分十进制字符串ip地址转为整形数据serveraddr.sin_addr.s_addr = inet_addr(argv[1]); // ip地址// atoi 将数字型字符串转换为整形数据// htons 将主机字节序转化为网络字节序serveraddr.sin_port = htons(atoi(argv[2]));// 将套接字和网络信息绑定if(bind(sockfd,(struct sockaddr*)&serveraddr, addrlen) == -1){perror("fail to connect");exit(1);};// 将套接字设置为监听状态if(listen(sockfd,5) == -1){perror("fail to listen");exit(1);}struct sockaddr_in clientsock;addrlen = sizeof(clientsock);printf("准备阻塞...\n");// 使用信号,异步的方式处理僵尸进程signal(SIGCHLD,handler);while(1){ // 阻塞等待客户端的链接int clisock = accept(sockfd,(struct sockaddr*)&clientsock, &addrlen);// 创建子线程与客户端通信MSG msg;msg.addr = clientsock;msg.acceptfd = clisock;pthread_t thread;if(pthread_create(&thread,NULL,pthread_fun,&msg)!=0){perror("fail to pthread_create");}pthread_detach(thread);}// 关闭套接字描述符//close(clisock);//close(sockfd);return 0; }

 

总结

以上是生活随笔为你收集整理的计算机网络:TCP的全部内容,希望文章能够帮你解决所遇到的问题。

如果觉得生活随笔网站内容还不错,欢迎将生活随笔推荐给好友。