Experiment 0x1:TCP套接字编程

0x0 说明

实验一:TCP套接字编程或UDP套接字编程

此篇为第一部分:TCP套接字编程

记录实验课代码

代码环境:

win10

VS2019 远程连接 ubuntu20

进行linux编程

0x1 要求

要求:实现一个基于TCP协议的服务器-客户端程序,要求完成以下功能。

  • 客户端:

    • 从命令行读入服务器的IP地址;并连接到服务器;
    • 接收从服务器端发送来的文件的内容,并存为一个文件. 服务器端关闭连接以后, 客户端就退出.
    • 显示总共接收到的字节数;
  • 服务器端:

    • 循环接收客户的连接请求,并显示客户的IP地址和端口号;
    • 发送硬盘上的一个文件到客户端,发送完毕以后断开连接;发送过程不断显示已发送的字节数.

0x2 实现

实现一个基于TCP协议的服务器-客户端程序

在这里插入图片描述

0x3 源码

1- TCP服务端源码

#include<stdio.h>
#include<string.h>
#include<unistd.h>
#include<sys/types.h>
#include<sys/socket.h>
#include<stdlib.h>
#include<fcntl.h>
#include<netinet/in.h>
#include<arpa/inet.h>

#define PORT 2333
#define BACKLOG 1

main() {
	int listenfd;
	sockaddr_in server;
	sockaddr_in client;
	socklen_t addrlen;

	listenfd = socket(AF_INET, SOCK_STREAM, 0);
	if (listenfd == -1) {
		perror("socket() error.");
		_exit(1);
	}

	int opt = SO_REUSEADDR;
	setsockopt(listenfd, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt));

	bzero(&server, sizeof(sockaddr_in));
	server.sin_family = AF_INET;
	server.sin_port = htons(PORT);
	server.sin_addr.s_addr = htonl(INADDR_ANY);
	
	int flag = bind(listenfd, (sockaddr*)&server, sizeof(sockaddr));
	if (flag == -1) {
		perror("Bind() error.");
		_exit(1);
	}
	flag = listen(listenfd, BACKLOG);
	if (flag == -1) {
		perror("listen() error.");
		_exit(1);
	}
	printf("Waiting for the connection.......\n");
	int len = sizeof(sockaddr_in);
	while (1) {
		int fd = open("./1111", O_RDONLY);
		if (fd <0) {
			perror("open() error!");
			_exit(1);
		}
		long CurToEnd = lseek(fd, 0, SEEK_END);
		lseek(fd, 0, SEEK_SET);
		int DataChunk = 100;
		int TotalSend = 0;

		
		int connectfd = accept(listenfd, (sockaddr*)&client, &addrlen);
		if (connectfd == -1) {
			perror("accept() error\n");
			_exit(1);
		}
		int SizeOfData = CurToEnd;
		while (CurToEnd) {
			if (CurToEnd < DataChunk) {
				DataChunk = CurToEnd;
			}
			char buf[100];
			memset(buf, 0, sizeof(buf));
			read(fd, buf, DataChunk);



			send(connectfd, buf, DataChunk, 0);
			CurToEnd -= DataChunk;
			TotalSend += DataChunk;

			system("clear");
			printf("You got a  connection from client's ip is %s, port is %d\n",
				inet_ntoa(client.sin_addr), ntohs(client.sin_port));
			//printf("The server has successfully sent %d bytes of data to the client, IP: %s\n", TotalSend,inet_ntoa(client.sin_addr));
			
			int percent = (TotalSend*100) / SizeOfData;
			
			int i = 0;
			printf("[");
			for (i = 0; i < percent/2; i++) {

				printf("*");
			}
			for (; i < 50; i++) {
				printf("#");
			}
			printf("] %d\%\n",percent);

			printf("has sent %d bytes!\n", TotalSend);


			if (CurToEnd == 0) {
				printf("Successfully! All data has been sent!\n");
				break;
			}
			
		}
		close(fd);
		close(connectfd);

		printf("Waiting for the Next connection.......\n");

	}

	
	close(listenfd);
	return 0;
}

2- TCP客户端源码

#include<stdio.h>
#include<unistd.h>
#include<string.h>
#include<sys/types.h>
#include<sys/socket.h>
#include<stdlib.h>
#include<fcntl.h>
#include<netinet/in.h>
#include<netdb.h>

#define PORT 2333
#define MAXDATASIZE 100
int main(int argc, char* argv[]) {
	int sockfd;
	char buf[MAXDATASIZE];
	hostent* he;
	sockaddr_in server;

	if (argc != 2) {
		printf("Usage:%s <IP Address>\n", argv[0]);
		_exit(1);
	}

	he = gethostbyname(argv[1]);
	if (he == NULL) {
		perror("gethostbyname() error.");
		_exit(1);
	}
	sockfd = socket(AF_INET, SOCK_STREAM, 0);
	if (sockfd == -1) {
		perror("socket() error.");
		_exit(1);
	}
	bzero(&server, sizeof(sockaddr_in));
	server.sin_family = AF_INET;
	server.sin_port = htons(PORT);
	server.sin_addr = *(in_addr*)(he->h_addr_list[0]);


	int flag = connect(sockfd, (sockaddr*)&server, sizeof(sockaddr_in));
	if (flag == -1) {
		perror("connect() error.\n");
		_exit(1);
	}
	printf("You have connected to the server!\n");
	int fd = open("./1111", O_WRONLY | O_CREAT, S_IRWXU);
	if (fd == -1) {
		perror("open() error.");
		_exit(1);
	}
	
	int TotalData = 0;

	while (1) {
		int num = recv(sockfd, buf, MAXDATASIZE, 0);
		
		if (num == -1) {
			printf("recv() error.\n");
			_exit(1);
		}
		else if (num == 0 ) {//服务器断开连接后,客户端recv返回0
			printf("Data receiving completed!\n");
			break;
		}
		TotalData += num;

		write(fd, buf, num);

	}
	printf("A total of %x bytes received", TotalData);
	close(fd);
	
	printf("server message: %s\n", buf);
	close(sockfd);

	return 0;
}

Logo

更多推荐