1.TCP编程流程

1.1TCP服务器端客户端及方法介绍

TCP 提供的是面向连接的、可靠的、字节流服务。TCP 的服务器端和客户端编程流程如下:

socket()方法是用来创建一个套接字,有了套接字就可以通过网络进行数据的收发。这也是为什么进行网络通信的程序首先要创建一个套接字。创建套接字时要指定使用的服务类型,使用 TCP 协议选择流式服务(SOCK_STREAM)。
bind()方法是用来指定套接字使用的 IP 地址和端口。IP 地址就是自己主机的地址,如果主机没有接入网络,测试程序时可以使用回环地址“127.0.0.1”。端口是一个 16 位的整形值,一般 0-1024 为知名端口,如 HTTP 使用的 80 号端口。这类端口一般用户不能随便使用。其次,1024-4096 为保留端口,用户一般也不使用。4096 以上为临时端口,用户可以使用。在Linux 上,1024 以内的端口号,只有 root 用户可以使用。
listen()方法是用来创建监听队列。监听队列有两种,一个是存放未完成三次握手的连接,一种是存放已完成三次握手的连接。listen()第二个参数就是指定已完成三次握手队列的长度。
accept()方法处理存放在 listen 创建的已完成三次握手的队列中的连接。每处理一个连接,则accept()返回该连接对应的套接字描述符。如果该队列为空,则 accept 阻塞。
connect()方法一般由客户端程序执行,需要指定连接的服务器端的 IP 地址和端口。该方法执行后,会进行三次握手,建立连接。

send()方法用来向 TCP 连接的对端发送数据。send()执行成功,只能说明将数据成功写入到发送端的发送缓冲区中,并不能说明数据已经发送到了对端。send()的返回值为实际写入
到发送缓冲区中的数据长度。
recv()方法用来接收 TCP 连接的对端发送来的数据。recv()从本端的接收缓冲区中读取数据,如果接收缓冲区中没有数据,则 recv()方法会阻塞。返回值是实际读到的字节数,如果
recv()返回值为 0, 说明对方已经关闭了 TCP 连接。
close()方法用来关闭 TCP 连接。此时,会进行四次挥手。

1.2服务端客服端示例代码

TCP服务端代码示例(方法参数意思参考套接字地址结构和网络编程接口):

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<unistd.h>
#include<assert.h>
#include<sys/socket.h>
#include<arpa/inet.h>int main()
{int sockfd = socket(AF_INET,SOCK_STREAM,0);assert(sockfd != -1);struct sockaddr_in saddr;memset(&saddr,0,sizeof(saddr));saddr.sin_family = AF_INET;saddr.sin_port = htons(6000);//将短整形主机字节转换为网络字节saddr.sin_addr.s_addr = inet_addr("127.0.0.1");//回环地址int res = bind(sockfd,(struct sockaddr*)&saddr,sizeof(saddr));assert(res != -1);res = listen(sockfd,5);assert(res != -1);while(1)//服务器循环接收客户端连接{struct sockaddr_in caddr;int len = sizeof(caddr);int c = accept(sockfd,(struct sockaddr*)&caddr,&len);if(c == -1){perror("accept error");continue;}printf("accept c = %d\n",c);char data[128];int n = recv(c,data,127,0);//阻塞printf("n = %d,buff = %s\n",n,data);send(c,"OK",2,0);close(c);}close(sockfd);exit(0);}

TCP客户端代码示例

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<unistd.h>
#include<assert.h>
#include<sys/socket.h>
#include<arpa/inet.h>int main()
{int sockfd = socket(AF_INET,SOCK_STREAM,0);assert(sockfd != -1);struct sockaddr_in saddr;saddr.sin_port = htons(6000);saddr.sin_family = AF_INET;saddr.sin_addr.s_addr = inet_addr("127.0.0.1");int res = connect(sockfd,(struct sockaddr*)&saddr,sizeof(saddr));assert(res != -1);printf("please input:");fflush(stdout);char buff[128] = {0};fgets(buff,127,stdin);send(sockfd,buff,strlen(buff),0);char data[128] = {0};int n = recv(sockfd,data,127,0);printf("%s\n",data);close(sockfd);exit(0);}

运行结果(服务端):

客户端:

客户端循环发送示例代码

#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include<unistd.h>
#include<assert.h>
#include<sys/socket.h>
#include<arpa/inet.h>int main()
{int sockfd = socket(AF_INET,SOCK_STREAM,0);assert(sockfd != -1);struct sockaddr_in saddr;memset(&saddr,0,sizeof(saddr));saddr.sin_family = AF_INET;saddr.sin_port = htons(6000);saddr.sin_addr.s_addr = inet_addr("127.0.0.1");int res = connect(sockfd,(struct sockaddr*)&saddr,sizeof(saddr));assert(res != -1);while(1){char buff[128] = {0};printf("input:\n");fgets(buff,127,stdin);if(strncmp(buff,"end",3) == 0){break;}send(sockfd,buff,strlen(buff),0);memset(buff,0,128);recv(sockfd,buff,127,0);printf("buff = %s\n",buff);}close(sockfd);
}

2.端口号占用问题

当我们执行完服务端客户端代码后,再次执行客户端的时候发现执行不起来:

这个assert断言是下图这个地方出现问题。

这是怎么回事呢?
这是因为我们对上次服务端执行后,端口还没来得及释放,6000这个端口仍然被占用着。我们可以用命令netstat -anp | grep +端口号或者netstat -tunlp | grep + 端口号查看这个端口被哪个进程占用着。注意:LISTEN才表示正在被占用


也可以使用netstat -nultp命令查看当前所有已经使用的端口的情况。

socket网络编程——TCP编程流程及端口号占用问题相关推荐

  1. 【Java 18】网络编程 - 概述、网络编程要素、IP和端口号、网络协议、TCP、UDP、URL

    网络编程 - 概述.网络编程要素.IP和端口号.网络协议.TCP.UDP.URL 网络编程 1 网络编程概述 2 网络通信要素概述 3 通信要素1:IP和端口号 3.1 内容 3.2 InetAddr ...

  2. C语言笔记(27)网络编程-TCP编程

    CS模式 有个服务器, 有个客户端, 会经过一些函数 linux下,所有的操作都是对文件进行操作,而对文件的操作是利用文件描述符(file descriptor)来实现的.每个文件进程控制块中都有一份 ...

  3. socket中的TCP编程(调用免费聊天的机器人实现自动回复)

    socket中的TCP编程(调用免费聊天的机器人实现自动回复) 在无聊时间复习了socket编程,写了这个简易代码!!注意要在联网状态下跑 1:服务器模块: import socket import ...

  4. Vue项目端口号占用

    问题描述: 今天在启动一个Vue项目的时候,遇到了一个问题. 得知是Vue项目端口号占用的问题.   解决方法: 换一个端口号. 在调用  npm run dev 的时候,实际上是在调用根目录下的 p ...

  5. mysqld占用mysql端口_IDEA连接不上MySQL端口号占用的解决

    命令行下能正常登陆MYSQL,navicat能正常连接MySQL,但是IDEA连接不上MySQL,emmm,什么情况... 看了一下错误提示: 一直以为是MySQL密码或者是访问权限的问题. 困扰n天 ...

  6. C#中开发之Socket网络编程TCP/IP层次模型、端口及报文等探讨

    我们在讲解Socket编程前,先看几个和Socket编程紧密相关的概念 1.TCP/IP层次模型 当然这里我们只讨论重要的四层 01,应用层(Application):应用层是个很广泛的概念,有一些基 ...

  7. Linux 网络编程——TCP编程

    概述 TCP(Transmission Control Protocol 传输控制协议)是一种面向连接的.可靠的.基于字节流的传输层通信协议. TCP 具有以下特点: 1)电话系统服务模式的抽象 2) ...

  8. GO语言使用之网络编程(TCP编程)

    一.基本介绍 Golang的主要设计目标之一就是面向大规模后端服务程序,网络通信这块是服务端 程序必不可少也是至关重要的一部分. 1. 网络编程有两种: TCP socket编程,是网络编程的主流.之 ...

  9. 网络编程——TCP编程

    一.概述 计算机网络是指两台或更多计算机组成的网络,在同一网络中,任意两台计算机都可以直接通信,因为所有计算机都需要遵循同一协议. 互联网是网络的网络,即把很多计算机网络连接起来,形成一个全球统的网络 ...

最新文章

  1. JAVA课上动手动脑问题以及课后测试1,2总结
  2. 【漫画】以后在有面试官问你AVL树,你就把这篇文章扔给他。
  3. 偷懒日志 - 自动生成代码 - 第二步 生成POJO
  4. postgresql - mac 启动 关闭 postgresql
  5. 十年只为一个摧残的梦(转载)
  6. 快速了解云原生中的微服务应用(内含福利)
  7. linux驱动编写(platform总线和网卡驱动)
  8. candence pcb走线等长_Allegro的通用等长规则设置方法
  9. jupyter一直*_不用下载安装,你的机器人可以直接在浏览器里跳舞丨Jupyter-ROS
  10. rk修改launcher_RK launcher V 0.41 官方版
  11. pip 清华大学镜像_pip源很慢,更改成清华的镜像地址
  12. bash sbin/start-yarn.sh出现localhost: rcmd: socket: Permission denied
  13. Luarocks 安装遇到的坑
  14. Python文本挖掘练习(一)// 新闻摘要
  15. 三星修复软件+连接三星认证服务器,三星云服务从2月6日起不再支持第三方应用程序数据备份...
  16. python学习笔记之序列,内含列表和元组的常用方法
  17. apex数据中心怎么切换服务器,Apex英雄怎么切换服务器
  18. js实现粘贴板js插件clipboard.js实现一键复制粘贴功能
  19. android textview 显示表情和文字 表情带超链接
  20. Springboot 设置上传文件大小

热门文章

  1. 100%测试覆盖率真的有用吗?
  2. MemoryStream 反序列化的报错问题
  3. 安卓下的免费离线地图导航软件(老虎地图)测试及网盘下载
  4. [网络安全自学篇] 三十三.文件上传之绕狗一句话原理和绕过安全狗(六)
  5. 2019年第十届蓝桥杯 - 省赛 - C/C++大学A组 - D. 迷宫
  6. HTML编码问题导致的乱码
  7. Spark is not running in local mode, therefore the checkpoint directory must not be on the local……
  8. 《每日一题》48. Rotate Image 旋转图像
  9. 78. Subsets 子集
  10. 2018\National _C_C++_B\1.换零钞