C语言网络编程(2)— TCP通信(转载)

2023-05-16

转载自:C语言网络编程(2)— TCP通信_Willliam_william的博客-CSDN博客_c语言tcp网络编程

C语言网络编程

2



TCP通信

Willliam_william 2020-04-15 18:03:51

958  正在上传…重新上传取消​ 收藏 12 

分类专栏: C语言网络编程

版权

​ C语言网络编程  专栏收录该内容

7 篇文章 0 订阅

订阅专栏



C语言网络编程2 TCP通信



一、TCP客户端

1、建立连接
我们要使用到socket,首先首先我们添加要使用的头文件

#include <stdio.h>
#include <string.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <arpa/inet.h>
#include <unistd.h>

创建一个tcp套接字,ipv4协议,使用SOCK_STREAM参数,protocol为0,就会默认自动选择tcp协议;

    // 1、使用socket()函数获取一个socket文件描述符
	int tcp_client = socket(AF_INET, SOCK_STREAM, 0);

然后我们把把服务端的ip地址和端口号放在一个结构体里准备好

    // 2、准备服务端的地址和端口,'192.168.0.107'表示目的ip地址,12341表示目的端口号
    struct sockaddr_in server_addr = {0};	
	server_addr.sin_family = AF_INET;                           // 设置地址族为IPv4
	server_addr.sin_port = htons(12341);						// 设置地址的端口号信息
	server_addr.sin_addr.s_addr = inet_addr("192.168.0.107");	// 设置IP地址

然后使用connect方法进行连接即可,连接成功则返回0.失败返回-1

    // 3、链接到服务器
    ret = connect(tcp_client, (const struct sockaddr *)&server_addr, sizeof(server_addr));
    if (ret < 0)
		perror("connect");
    else
	    printf("connect result, ret = %d.\n", ret);

最后记得关闭套接字即可

    // 4、关闭套接字
    close(tcp_client);

编译运行,连接成功:
在这里插入图片描述
在这里插入图片描述
2、发送数据
使用send()函数发送数据

    // 4. 发送数据到服务端
	char sendbuf[]={"hello world."};
	ret = send(sockfd, sendbuf, strlen(sendbuf),0);

可以看到,数据发送成功,服务器端已经接收到数据
在这里插入图片描述
3、接收数据
如果要接收数据,那么就可以使用recv函数等待接收即可,其参数为最大接收字节数,然后将接收到的数据 打印出来
在这里插入图片描述
在这里插入图片描述

完整代码如下:

#include <stdio.h>
#include <string.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <arpa/inet.h>
#include <unistd.h>

int main(void)
{
    int ret;
    // 1、使用socket()函数获取一个TCP客户端socket文件描述符
	int tcp_client = socket(AF_INET, SOCK_STREAM, 0);
    if (-1 == tcp_client)
	{
		perror("socket");
		return -1;
	}

    // 2、准备服务端的地址和端口,'192.168.0.107'表示目的ip地址,12341表示目的端口号
    struct sockaddr_in server_addr = {0};	
	server_addr.sin_family = AF_INET;                           // 设置地址族为IPv4
	server_addr.sin_port = htons(12341);						// 设置地址的端口号信息
	server_addr.sin_addr.s_addr = inet_addr("192.168.0.107");	// 设置IP地址

    // 3、链接到服务器
    ret = connect(tcp_client, (const struct sockaddr *)&server_addr, sizeof(server_addr));
    if (ret < 0)
		perror("connect");
    else
	    printf("connect result, ret = %d.\n", ret);

    // 4. 发送数据到服务端
	char sendbuf[]={"hello world."};
	ret = send(tcp_client, sendbuf, strlen(sendbuf),0);

    // 5、等待接收服务端发送过来的数据,最大接收1024个字节
    char recvbuf[1024] = {0};
    ret = recv(tcp_client, recvbuf, sizeof(recvbuf), 0);

    // 6、将接收到的数据打印出来
    printf("Recvdate:%s \n",recvbuf);

    // 7、关闭套接字
    close(tcp_client);
}



二、TCP服务端

1、建立服务端,等待连接
同样的,我们要使用到socket,首先首先我们添加要使用的头文件

#include <stdio.h>
#include <string.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <arpa/inet.h>
#include <unistd.h>

创建一个tcp套接字,ipv4协议,使用SOCK_STREAM参数,protocol为0,就会默认自动选择tcp协议;

    // 1、使用socket()函数获取一个socket文件描述符
	int tcp_server = socket(AF_INET, SOCK_STREAM, 0);

为了让客户端可以连接到,我们需要绑定一个端口号

    // 2. 绑定本地的相关信息,如果不绑定,则系统会随机分配一个端口号
    struct sockaddr_in local_addr = {0};
    local_addr.sin_family = AF_INET;		                    // 设置地址族为IPv4
	local_addr.sin_port = htons(8266);	                        // 设置地址的端口号信息
	local_addr.sin_addr.s_addr = inet_addr("192.168.0.107");	// 设置IP地址
	ret = bind(tcp_server, (const struct sockaddr *)&local_addr, sizeof(local_addr));
	if (ret < 0)
		perror("bind");
    else	
        printf("bind success.\n");

然后我们就可以使用listen方法来监听连接了,第二个参数为可以等待的排队连接数量

    // 3、listen监听端口,阻塞,等待客户端来连接服务器
	ret = listen(sockfd, 5);

使用accept方法来等待客户端连接到这个服务器,其返回值为连接过来的客户端套接字文件描述符

    // 4、accept阻塞等待客户端接入
    struct sockaddr_in client_addr;
    socklen_t addrlen = sizeof(client_addr);
	int client_fd = accept(tcp_server, (struct sockaddr *)&client_addr, &addrlen);

我们将其链接过来的客户端信息打印出来

    // 5、打印连接过来的客户端信息及其ip地址
    printf("Client from %s:%d \n",inet_ntoa(*(struct in_addr*)&client_addr.sin_addr.s_addr),ntohs(client_addr.sin_port));

然后我们就可以关闭套接字了

     // 6、关闭套接字
    close(tcp_client);

运行程序,使用网络调试助手进行连接,可以看到,连接成功
在这里插入图片描述
在这里插入图片描述
2、接收数据
当有客户端连接进来时,我们就可以使用客户端套接字文件描述符等待接收对方发送过来的数据了

// 5、等待接收对方发送过来的数据
    char recvbuf[1024] = {0};
    ret = recv(client_fd, recvbuf, sizeof(recvbuf), 0);
    printf("Recv from %s:%d, ",inet_ntoa(*(struct in_addr*)&client_addr.sin_addr.s_addr),ntohs(client_addr.sin_port));
    printf("recv_data: %s \n",recvbuf);

编译,运行,使用网络调试助手客户端发送数据,结果如下
在这里插入图片描述
3、发送数据
接收到数据以后我们发送数据回去,告诉客户端我已经接受到数据了

    // 6、返回数据到客户端
    char send_buf[1024] = "I have got the date:";
    strcat(send_buf,recvbuf);
    send(client_fd, send_buf, strlen(send_buf), 0);

编译,运行结果
在这里插入图片描述
完整代码

#include <stdio.h>
#include <string.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <arpa/inet.h>
#include <unistd.h>

int main(void)
{
    int ret = -1;
    // 1、使用socket()函数获取一个socket文件描述符
	int tcp_server = socket(AF_INET, SOCK_STREAM, 0);
    if (-1 == tcp_server)
	{
		perror("socket");
		return -1;
	}

    // 2. 绑定本地的相关信息,如果不绑定,则系统会随机分配一个端口号
    struct sockaddr_in local_addr = {0};
    local_addr.sin_family = AF_INET;		                    // 设置地址族为IPv4
	local_addr.sin_port = htons(8266);	                        // 设置地址的端口号信息
	local_addr.sin_addr.s_addr = inet_addr("192.168.0.107");	// 设置IP地址
	ret = bind(tcp_server, (const struct sockaddr *)&local_addr, sizeof(local_addr));
	if (ret < 0)
		perror("bind");
    else	
        printf("bind success.\n");

    // 3、listen监听端口,阻塞,等待客户端来连接服务器
	ret = listen(tcp_server, 5);

    // 4、accept阻塞等待客户端接入
    struct sockaddr_in client_addr;
    socklen_t addrlen = sizeof(client_addr);
	int client_fd = accept(tcp_server, (struct sockaddr *)&client_addr, &addrlen);

    // 5、等待接收对方发送过来的数据
    char recvbuf[1024] = {0};
    ret = recv(client_fd, recvbuf, sizeof(recvbuf), 0);
    printf("Recv from %s:%d, ",inet_ntoa(*(struct in_addr*)&client_addr.sin_addr.s_addr),ntohs(client_addr.sin_port));
    printf("recv_data: %s \n",recvbuf);

    // 6、返回数据到客户端
    char send_buf[1024] = "I have got the date:";
    strcat(send_buf,recvbuf);
    send(client_fd, send_buf, strlen(send_buf), 0);

     // 7、关闭套接字
    close(tcp_server);
}

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

C语言网络编程(2)— TCP通信(转载) 的相关文章

  • 如何在java应用程序中检测FIN - tcp标志?

    我在两台计算机之间有持久的 TCP 连接 第二台计算机不受我的控制 第二台计算机可以随时发送FIN标志 并且首先必须关闭当前连接 将FIN标志发送回第二台计算机 我如何知道第二台计算机正在发送 FIN 标志 以及何时必须调用 Java 应用
  • 数据包丢失和数据包重复

    我试图找出数据包丢失和数据包重复问题之间的区别 有谁知道 数据包重复 是什么意思 和TCP检测到丢失时重传数据包一样吗 No In TCP 数据包 的传递是可靠的 我认为在这种情况下术语数据应该更好 因为它是面向流的协议 数据包丢失和重复是
  • 如何在Linux中打开端口[关闭]

    Closed 这个问题不符合堆栈溢出指南 help closed questions 目前不接受答案 我已经安装了 Web 应用程序 该应用程序在 RHEL centOS 上的端口 8080 上运行 我只能通过命令行访问该机器 我尝试从我的
  • AMQP如何克服直接使用TCP的困难?

    AMQP如何克服直接使用TCP发送消息时的困难 或者更具体地说 在发布 订阅场景中 在 AMQP 中 有一个代理 该代理接收消息 然后完成将消息路由到交换器和队列的困难部分 您还可以设置持久队列 即使客户端断开连接 也可以为客户端保存消息
  • 自动打开命名管道和 tcp\ip

    我正在安装一个需要修改 SQL Server 的新产品 具体来说 启用 tcp ip 并打开命名管道 我知道如何手动完成 我想要的是一种通过 SQL 或 C 代码为新客户自动化执行此操作的方法 我希望有任何关于正确方向的建议 您可以使用 C
  • 我应该害怕使用 UDP 进行客户端/服务器广播通话吗?

    我在过去的两天里阅读了每一篇StackOverflow问题和答案 以及googling当然 关于印地TCP and UDP协议 以便决定在我的用户应用程序和 Windows 服务之间的通信方法中应该使用哪一种 从我目前所看到的来看 UDP是
  • 序列化是通过套接字发送数据的最佳选择吗?

    有人告诉我 序列化不是通过套接字发送数据的最佳方法 但他们说他们在一本书上读过一次 并且不确定更好的方法 因为他们以前没有真正做过网络 那么序列化是最好的方法还是有更好的方法 如果这有很大的不同的话 这也是一个游戏 通过搜索有关通过它发送对
  • 为什么tcp终止需要4次握手?

    当连接建立时 有 客户端 SYN gt 服务器 客户端 客户端 ACK gt 服务器 当终止到来时 有 客户端 FIN gt 服务器 客户端 客户端 客户端 ACK gt 服务器 我的问题是为什么 和 不能像 那样设置在同一个包中 即ACK
  • 计算 TCP 重传次数

    我想知道在LINUX中是否有一种方法可以计算一个流中发生的TCP重传的次数 无论是在客户端还是服务器端 好像netstat s解决了我的目的
  • 使用 TCP 时是否需要使用校验和来保护我的消息?

    使用 TCP 作为网络协议 在通过线路发送消息之前 我会为每条消息的大小 以及可能的校验和 添加前缀 我想知道 计算和传输消息的校验和是否有意义 以确保消息将被不变地传递 如果以及何时传递 例如因为一些网络错误 目前 我在发送消息本身之前发
  • 用 C 语言进行非阻塞 udp 套接字编程:我能得到什么?

    我在理解从非阻塞 UDP 套接字返回什么recv recvfrom 时遇到问题 与 TCP 相比更具体一点 如果我错了 请纠正我 阻塞套接字 TCP 或 UDP 在缓冲区中有一些数据之前不会从 recv 返回 这可以是一定数量的字节 TCP
  • Silverlight 套接字:模仿框架 Bind、Listen 和 Accept 方法?

    我有这个 NET Framework C 类 它实际上充当 TCP 连接的包装器Socket http msdn microsoft com en us library attbb8f5 aspxSystem Net Sockets 命名空
  • NodeJS:TCP套接字服务器仅在第一次返回数据

    我正在尝试在 node js 中编写一个小型中继脚本 用于侦听本地套接字上传入的 TCP 连接 当它收到连接时 将流量转发给第三方 它还必须从该第三方获取任何返回的数据并将其发送回原始本地套接字 我试过类似的代码http delog wor
  • 具有非阻塞或多线程功能的 Ruby Tcp Server 类

    找不到任何可以帮助创建非阻塞 多线程服务器的 gem 或类 哪里可以找到 The Ruby 文档 http ruby doc org core classes Socket html M002091关于套接字有一些很好的例子 使用该页面中的
  • TCL类C10K事件服务器开发进展如何?

    TCL 是一种很好的简单编程语言 但似乎没有得到认可和 或尊重它deserves http antirez com articoli tclmisunderstood html 我 1995 年在大学时就学过它 但很快就忘记了 直到最近才再
  • PHP 通过 TCP/IP 发送消息

    我尝试通过 TCP IP 从 PHP 网站向 Arduino 发送消息 使用以下代码我可以从 php 网站发送消息 问题是 当第一次调用该网站时 消息不会立即发送 网站刷新几次后 消息就会到达 但逻辑上很多次 就像网站刷新量一样 已经尝试将
  • python 中的原始套接字和 sendto

    我正在努力将 scapy 与twisted 集成 但我在 OSX 上遇到了这个非常奇怪的错误 我似乎无法弄清楚 基本上我无法通过原始套接字发送有效的 TCP 数据包 包括 IP 标头 这就是我正在做的 import socket from
  • 确定 TCP Listen() 队列中当前积压的连接数

    有没有办法找出currentLinux 上 TCP 套接字上等待 Accept 的连接尝试次数 我想我可以在每个事件循环上点击 EWOULDBLOCK 之前计算成功的 Accept 数量 但我使用的是隐藏这些细节的高级库 Python Tw
  • TCP 校验和可能无法检测到错误吗?如果是的话,这件事是如何处理的?

    如果 TCP 有效负载在传输过程中被损坏 则重新计算的校验和将与传输的校验和不匹配 太好了 到目前为止一切都很好 如果 TCP 校验和在传输过程中损坏 则重新计算的校验和将与现在损坏的校验和不匹配 太好了 到目前为止一切都很好 当有效负载和
  • 如何才能将 TCP 连接返回到同一端口?

    机器是 RHEL 5 3 内核 2 6 18 有时我在 netstat 中注意到我的应用程序有连接 建立了 TCP 连接本地地址 and 国外地址是一样的 其他人也报告了同样的问题 症状与链接中描述的相同 客户端连接到本地运行的服务器的端口

随机推荐