网络通信1—TCP程序编写步骤(参照 Ubuntu 16.04 版本)

  • TCP基础模型
  1. 服务器流程
    1. step 1:创建 socke() 套接字接口并判断
listenfd = socket(AF_INET, SOCK_STREAM, 0);
if (listenfd == -1)
{perror("socket failed");return -1;}
  1. step 2:设置 IP 和 Port
memset (&seraddr, 0, sizeof(seraddr));
seraddr.sin_family = AF_INET;
seraddr.sin_port = htons(8888);
seraddr.sin_addr.s_addr = inet_addr("127.0.0.1");
  1. step 3:绑定 IP 和 Port 并判断
ret = bind(listenfd, (struct sockaddr *)&seraddr, sizeof(seraddr));
if (ret == -1)
{perror("bind failed");return -1;}
  1. step 4:监听连接并判断
ret = listen(listenfd, 5);
if (ret == -1)
{perror("listen failed");return -1;}
  1. step 5:接受连接请求并判断
connfd = accept(listenfd, (struct sockaddr *)&cliaddr, &addrlen);
if (connfd == -1)
{perror("accept failed");return -1;}
printf("connect sucessfully: client IP: %s, Port: %d\n", inet_ntoa(cliaddr.sin_addr), ntohs(cliaddr.sin_port));
  1. step 6:接收数据并判断
ret = recv(connfd, buf, sizeof(buf), 0);
if (ret == -1)
{perror("recv failed");return -1;}
printf("recv from client: %s\nrecv %d bytes\n", buf, ret);
  1. step 7:发送数据并判断
ret = send(connfd, buf, sizeof(buf), 0);
if (ret == -1)
{perror("send failed");return -1;}
printf("send successfully!\n");
  1. step 8:关闭连接
close(connfd);
  1. step 9:检查头文件和变量是否定义
客户端流程
  1. step 1:创建 socke() 套接字接口并判断
connfd = socket(AF_INET, SOCK_STREAM, 0);
if (connfd == -1)
{perror("socket failed");return -1;}
  1. step 2:设置服务器 IP 和 Port
memset (&seraddr, 0, sizeof(seraddr));
seraddr.sin_family = AF_INET;
seraddr.sin_port = htons(8888);
seraddr.sin_addr.s_addr = inet_addr("127.0.0.1");
  1. step 3:发送连接请求并判断
ret = connect(connfd, (struct sockaddr *)&seraddr, sizeof(seraddr));
if (ret == -1)
{perror("connect faile");return -1;}
printf("connect sucessfully!\n");
  1. step 4:发送数据并判断
ret = send(connfd, buf, sizeof(buf), 0);
if (ret == -1)
{perror("send faile");return -1;}
printf("send successfully!");
  1. step 5:接收数据
ret = recv(connfd, buf, sizeof(buf), 0);
if (ret == -1)
{perror("recv faile");return -1;}
printf("%s\n", buf);
  1. step 6:关闭连接
close(connfd);
  1. step 7:检查头文件和变量是否定义
  • TCP 循环服务器模型
  1. 服务器流程
    1. step 1:创建 socke() 套接字接口并判断
listenfd = socket(AF_INET, SOCK_STREAM, 0);
if (listenfd == -1)
{perror("socket failed");return -1;}
  1. step 2:设置 IP 和 Port
memset (&seraddr, 0, sizeof(seraddr));
seraddr.sin_family = AF_INET;
seraddr.sin_port = htons(8888);
seraddr.sin_addr.s_addr = inet_addr("127.0.0.1");
  1. step 3:绑定 IP 和 Port 并判断
ret = bind(listenfd, (struct sockaddr *)&seraddr, sizeof(seraddr));
if (ret == -1)
{perror("bind failed");return -1;}
  1. step 4:监听连接并判断
ret = listen(listenfd, 5);
if (ret == -1)
{perror("listen failed");return -1;}
  1. step 5:设置循环连接
while(1)
  1. step 6:接受连接请求并判断
connfd = accept(listenfd, (struct sockaddr *)&cliaddr, &addrlen);
if (connfd == -1)
{perror("accept failed");return -1;}
printf("connect sucessfully: client IP: %s, Port: %d\n", inet_ntoa(cliaddr.sin_addr), ntohs(cliaddr.sin_port));
  1. step 7:循环接收数据,直达条件满足退出
while(1)
  1. step 8:接收数据并判断
ret = recv(connfd, buf, sizeof(buf), 0);
if (ret == -1)
{perror("recv failed");return -1;}
  1. step 9:设置跳出循环的条件
if (!strncmp("quit", buf, 4))
break;
printf("recv from client: %s\nrecv %d bytes\n", buf, ret);
  1. step 10:发送数据并判断
ret = send(connfd, buf, sizeof(buf), 0);
if (ret == -1)
{perror("send failed");return -1;}
printf("send successfully!\n");
  1. step 11:关闭连接
close(connfd);
  1. step 12:检查头文件和变量是否定义
客户端流程
  1. step 1:创建 socke() 套接字接口并判断
connfd = socket(AF_INET, SOCK_STREAM, 0);
if (connfd == -1)
{perror("socket failed");return -1;}
  1. step 2:设置服务器 IP 和 Port
memset (&seraddr, 0, sizeof(seraddr));
seraddr.sin_family = AF_INET;
seraddr.sin_port = htons(8888);
seraddr.sin_addr.s_addr = inet_addr("127.0.0.1");
  1. step 3:发送连接请求并判断
ret = connect(connfd, (struct sockaddr *)&seraddr, sizeof(seraddr));
if (ret == -1)
{perror("connect faile");return -1;}
printf("connect sucessfully!\n");
  1. step 4:设置数据循环,并获取标准输入的数据
while (1)
{fgets(buf, sizeof(buf), stdin);
buf[strlen(buf)-1] = '\0';
...}
  1. step 5:发送数据并判断
ret = send(connfd, buf, sizeof(buf), 0);
if (ret == -1)
{perror("send faile");return -1;}
printf("send successfully!");
  1. step 6:设置退出条件
if (!strncmp("quit", buf, 4))
break;
  1. step 7:接收数据
ret = recv(connfd, buf, sizeof(buf), 0);
if (ret == -1)
{perror("recv faile");return -1;}
printf("%s\n", buf);
  1. step 8:关闭连接
close(connfd);
  1. step 9:检查头文件和变量是否定义
  • TCP 并发服务器模型
  1. 服务器流程
    1. step 1:创建 socke() 套接字接口并判断
listenfd = socket(AF_INET, SOCK_STREAM, 0);
if (listenfd == -1)
{perror("socket failed");return -1;}
  1. step 2:设置 IP 和 Port
memset (&seraddr, 0, sizeof(seraddr));
seraddr.sin_family = AF_INET;
seraddr.sin_port = htons(8888);
seraddr.sin_addr.s_addr = inet_addr("127.0.0.1");
  1. step 3:绑定 IP 和 Port 并判断
ret = bind(listenfd, (struct sockaddr *)&seraddr, sizeof(seraddr));
if (ret == -1)
{perror("bind failed");return -1;}
  1. step 4:监听连接并判断
ret = listen(listenfd, 5);
if (ret == -1)
{perror("listen failed");return -1;}
  1. step 5:设置信号处理防止僵尸进程
signal(SIGCHLD, SIG_IGN);
  1. step 6:设置循环建立连接
while(1)
  1. step 7:接受连接请求并判断
connfd = accept(listenfd, (struct sockaddr *)&cliaddr, &addrlen);
if (connfd == -1)
{perror("accept failed");return -1;}
printf("connect sucessfully: client IP: %s, Port: %d\n", inet_ntoa(cliaddr.sin_addr), ntohs(cliaddr.sin_port));
  1. step 8:创建子进程并判断
pid = fork();
if (pid == -1)
{perror("fork create");return -1}
  1. step 9:设置父进程关闭连接并重新建立链接
if (pid > 0)
{close(connfd);continue;}
  1. step 10:子进程关闭监听,并循环接收数据
close(listenfd);
while(1)
  1. step 11:接收数据并判断
ret = recv(connfd, buf, sizeof(buf), 0);
if (ret == -1)
{perror("recv failed");return -1;}
  1. step 12:设置跳出循环的条件
if (!strncmp("quit", buf, 4))
break;
printf("recv from client: %s\nrecv %d bytes\n", buf, ret);
  1. step 10:发送数据并判断
ret = send(connfd, buf, sizeof(buf), 0);
if (ret == -1)
{perror("send failed");return -1;}
printf("send successfully!\n");
  1. step 11:关闭连接同时退出进程
close(connfd);
exit(0);
  1. step 12:检查头文件和变量是否定义
客户端流程
  1. step 1:创建 socke() 套接字接口并判断
connfd = socket(AF_INET, SOCK_STREAM, 0);
if (connfd == -1)
{perror("socket failed");return -1;}
  1. step 2:设置服务器 IP 和 Port
memset (&seraddr, 0, sizeof(seraddr));
seraddr.sin_family = AF_INET;
seraddr.sin_port = htons(8888);
seraddr.sin_addr.s_addr = inet_addr("127.0.0.1");
  1. step 3:发送连接请求并判断
ret = connect(connfd, (struct sockaddr *)&seraddr, sizeof(seraddr));
if (ret == -1)
{perror("connect faile");return -1;}
printf("connect sucessfully!\n");
  1. step 4:设置数据循环,并获取标准输入的数据
while (1)
{fgets(buf, sizeof(buf), stdin);
buf[strlen(buf)-1] = '\0';
...}
  1. step 5:发送数据并判断
ret = send(connfd, buf, sizeof(buf), 0);
if (ret == -1)
{perror("send faile");return -1;}
printf("send successfully!");
  1. step 6:设置退出条件
if (!strncmp("quit", buf, 4))
break;
  1. step 7:接收数据
ret = recv(connfd, buf, sizeof(buf), 0);
if (ret == -1)
{perror("recv faile");return -1;}
printf("%s\n", buf);
  1. step 8:关闭连接
close(connfd);
  1. step 9:检查头文件和变量是否定义
  • 2
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值