利用linux socket tcp 尝试发送长数据,在写的过程中,调用close,看看没发完的数据是否会继续发送;close之后TCP连接是否会断开

1.题目及解答

利用linux socket tcp 尝试发送长数据,在写的过程中,调用close,看看没发完的数据是否会继续发送;close之后TCP连接是否会断开,用两种方式查看,(1)netstat命令,(2)wireshark抓包工具,查看发送的数据能不能被抓到,查看三次握手和四次挥手发生的时间,(3)TCP client端的IP和port是由谁创建的?是多少?
修改的代码如所示:主要是用来交互信息的那部分,在客户端中初始化一段长数据,然后在写的过程中,调用close。
在这里插入图片描述
在这里插入图片描述
图 1 修改的代码
根据程序运行结果可以看到,预期发送的数据是102400bytes,但是服务器端实际接受的却只有14480bytes,说明close之后数据并未接收完全。
在这里插入图片描述
在这里插入图片描述

而根据抓包信息,通过计算观察,客户端其实已经发送了所有的数据,有三次握手但是并没有四次挥手,中间还有服务器试图和客户端重置连接,但由于最后客户端已经关闭,所有并没有完整的四次挥手。而利用netstat查看服务器端的端口8080发现也已经关闭。TCP client端的IP和port是由socket创建的,根据抓包信息,可以看到其值分别是192.168.61.129和38138。
在这里插入图片描述

2.源码

2.1服务端

#include <stdio.h> 
#include <netdb.h> 
#include <unistd.h> 
#include <stdlib.h> 
#include <string.h> 
#include <sys/socket.h> 
#include <arpa/inet.h>
#include <sys/types.h> 
#define MAX 102400
#define PORT 8080 
#define SA struct sockaddr 
  
// Function designed for chat between client and server. 
void func(int sockfd) 
{
    char buff[MAX];
    int n = 0;
    memset(buff, 'a', MAX); 

    // read the message from client and copy it in buffer 
    n = read(sockfd, buff, sizeof(buff));
    buff[n] = '\0';
    // print buffer which contains the client contents 
    printf("Total bytes received actually: %d\nServer has exited\n", n);
} 
  
// Driver function 
int main() 
{ 
    int sockfd, connfd, len; 
    struct sockaddr_in servaddr, cli; 
  
    // socket create and verification 
    sockfd = socket(AF_INET, SOCK_STREAM, 0); 
    if (sockfd == -1)
    { 
        printf("socket creation failed...\n"); 
        exit(0); 
    } 
    else
        printf("Socket successfully created..\n"); 
    bzero(&servaddr, sizeof(servaddr)); 
  
    // assign IP, PORT 
    servaddr.sin_family = AF_INET; 
    servaddr.sin_addr.s_addr = htonl(INADDR_ANY); 
    servaddr.sin_port = htons(PORT); 
  
    // Binding newly created socket to given IP and verification 
    if ((bind(sockfd, (SA*)&servaddr, sizeof(servaddr))) != 0) { 
        printf("socket bind failed...\n"); 
        exit(0); 
    } 
    else
        printf("Socket successfully binded..\n"); 
  
    // Now server is ready to listen and verification 
    if ((listen(sockfd, 5)) != 0)
    { 
        printf("Listen failed...\n"); 
        exit(0); 
    } 
    else
        printf("Server listening..\n"); 
    len = sizeof(cli); 
  
    // Accept the data packet from client and verification 
    connfd = accept(sockfd, (SA*)&cli, &len); 
    if (connfd < 0)
    { 
        printf("server acccept failed...\n"); 
        exit(0); 
    } 
    else
        printf("server acccept the client...\n"); 
  
    // Function for chatting between client and server 
    func(connfd); 
  
    // After chatting close the socket 
    close(sockfd); 
}

2.2客户端

#include <netdb.h>
#include <unistd.h> 
#include <stdio.h> 
#include <stdlib.h> 
#include <string.h> 
#include <sys/socket.h>
#include <arpa/inet.h>
#define MAX 102400 
#define PORT 8080 
#define SA struct sockaddr 
void func(int sockfd) 
{ 
	char buff[MAX];
	memset(buff, 'z', sizeof(buff));
    while (write(sockfd, buff, sizeof(buff)) > 0)
        close(sockfd);
    printf("Expected total bytes sent: %d\nClient has exit\n", MAX);
}

int main() 
{ 
	int sockfd, connfd; 
	struct sockaddr_in servaddr, cli; 

	// socket create and varification 
	sockfd = socket(AF_INET, SOCK_STREAM, 0); 
	if (sockfd == -1) { 
		printf("socket creation failed...\n"); 
		exit(0); 
	} 
	else
		printf("Socket successfully created..\n"); 
	bzero(&servaddr, sizeof(servaddr)); 

	// assign IP, PORT 
	servaddr.sin_family = AF_INET; 
	servaddr.sin_addr.s_addr = inet_addr("192.168.61.131"); 
	servaddr.sin_port = htons(PORT); 

	// connect the client socket to server socket 
	if (connect(sockfd, (SA*)&servaddr, sizeof(servaddr)) != 0) { 
		printf("connection with the server failed...\n"); 
		exit(0); 
	} 
	else
		printf("connected to the server..\n"); 

	// function for chat 
	func(sockfd); 

	// close the socket 
	close(sockfd); 
}
  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值