TCP套接字详解—C语言实现

基于C语言实现TCP套接字通信

本文旨在windows系统中使用TCP套接字实现客户端/服务端通信
编译器:visual studio 2019 (community)

Socket本意翻译为插座,这其实很形象的解释了套接字的作用,在客户端与服务端的通信中,套接字就起着像插座一样连接的作用。
TCP套接字与UDP套接字最大的区别便是是否面向连接,本文所实现的便是面向连接的TCP套接字,即客户端与服务端在通信之前进行三次握手建立连接。

TCP服务端建立步骤:

  1. 申请套接字:s = socket(…);
  2. 确定本地端点,填写端点地址:address = …;
  3. 建立套接字与端点关系(绑定):bind(s,address…);
  4. 设置为监听模式:listen(s);
  5. 接收连接:newsock = accept(s);
  6. 数据收/发:recv(newsock); / send(newsock);
  7. 关闭套接字:closesocket(newsock);

TCP客户端建立步骤:

  1. 申请套接字:s = socket(…);
  2. 确定本地端点,填写端点地址:c_address = …;
  3. 建立套接字与端点关系(绑定):bind(s,c_address…);
  4. 确定服务器端点:s_address = …;
  5. 与服务器建立连接:connect(s,s_address…);
  6. 数据发/收:send(s); / recv(s);
  7. 关闭套接字:closesocket(s);

TCP服务端代码实现


#include <stdio.h>
#include <winsock2.h>
#include <time.h>
#include <stdlib.h>
#include <math.h>
#pragma comment(lib,"ws2_32.lib")

int main(int argc, char* argv[])
{
	//初始化WSA
	WORD sockVersion = MAKEWORD(2, 2);
	WSADATA wsaData;
	if (WSAStartup(sockVersion, &wsaData) != 0)
	{
		return 0;
	}

	//创建套接字
	SOCKET slisten = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
	if (slisten == INVALID_SOCKET)
	{
		printf("socket error !");
		return 0;
	}

	//绑定IP和端口
	sockaddr_in sin;
	sin.sin_family = AF_INET;
	sin.sin_port = htons(8888);
	sin.sin_addr.S_un.S_addr = INADDR_ANY;
	if (bind(slisten, (LPSOCKADDR)& sin, sizeof(sin)) == SOCKET_ERROR)
	{
		printf("bind error !");
	}

	//开始监听
	if (listen(slisten, 5) == SOCKET_ERROR)
	{
		printf("listen error !");
		return 0;
	}

	//循环接收数据
	SOCKET sClient;
	sockaddr_in remoteAddr;
	int nAddrlen = sizeof(remoteAddr);
	char revData[255];
	while (true)
	{
		printf("等待连接...\n");
		sClient = accept(slisten, (SOCKADDR*)& remoteAddr, &nAddrlen);
		if (sClient == INVALID_SOCKET)
		{
			printf("accept error !");
			continue;
		}
		printf("接受到一个连接:%s \r\n", inet_ntoa(remoteAddr.sin_addr));



		srand((unsigned)time(NULL));
		
		for (int i = 0; i <= 20; i++)
		{//接收数据
			int ret = recv(sClient, revData, 255, 0);
			//int my_revdata = int(*revData);// *(int* (const char*)revData)
			int my_revdata = *((int*)(revData));
			if (ret > 0)
			{
				revData[ret] = 0x00;
				//int b = int(*revData);
				//printf(revData);
				printf("成功接受数据:%3d", my_revdata);
			}

			//发送数据
			int randData = rand() % 500;
			randData = abs(randData);
			int my_sendData = my_revdata + randData;
			printf("我发送的数据:%5d \n", my_sendData);
			send(sClient, (const char*)(&my_sendData), sizeof(my_sendData), 0);
	
		}
		closesocket(sClient);
	}

	closesocket(slisten);
	WSACleanup();
	return 0;
}

TCP客户端代码实现


#include <WINSOCK2.H>
#include <STDIO.H>
#include <time.h>
#include <stdlib.h>
#include <math.h>
#include<windows.h>

#pragma  comment(lib,"ws2_32.lib")

int main(int argc, char* argv[])
{
	WORD sockVersion = MAKEWORD(2, 2);
	WSADATA data;
	if (WSAStartup(sockVersion, &data) != 0)
	{
		return 0;
	}

	SOCKET sclient = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
	if (sclient == INVALID_SOCKET)
	{
		printf("invalid socket !");
		return 0;
	}

	sockaddr_in serAddr;
	serAddr.sin_family = AF_INET;
	serAddr.sin_port = htons(8888);
	serAddr.sin_addr.S_un.S_addr = inet_addr("127.0.0.1");
	if (connect(sclient, (sockaddr*)& serAddr, sizeof(serAddr)) == SOCKET_ERROR)
	{
		printf("connect error !");
		closesocket(sclient);
		return 0;
	}


	srand((unsigned)time(NULL));
	for (int i = 0; i < 20; i++)
	{
		Sleep(500);
		int a = rand() % 500;
		a = abs(a);
		printf("我发送的随机数:%3d ", a);
		
		send(sclient, (const char*)(&a), sizeof(a), 0);
		char recData[255];
		int ret = recv(sclient, recData, 255, 0);
		int d = *((int*)(recData));
		if (ret > 0)
		{
			recData[ret] = 0x00;
			if (d > 100)
			{
				printf("成功接收返回数据:");
				printf("%5d\n", d);
			}
			else
			{
				printf("数据不符合要求!\n");
			}
		}

	}
	closesocket(sclient);
	WSACleanup();
	return 0;
}
  • 12
    点赞
  • 54
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: 以下是 TCP 套接字编程使用 C 语言的示例代码: ```c #include <stdio.h> #include <stdlib.h> #include <string.h> #include <sys/socket.h> #include <arpa/inet.h> #include <unistd.h> #define SERVER_PORT 8080 int main(int argc, char *argv[]) { int sockfd; struct sockaddr_in servaddr; // 创建套接字 sockfd = socket(AF_INET, SOCK_STREAM, 0); if (sockfd == -1) { perror("socket"); exit(EXIT_FAILURE); } // 配置服务器地址信息 memset(&servaddr, 0, sizeof(servaddr)); servaddr.sin_family = AF_INET; servaddr.sin_port = htons(SERVER_PORT); if (inet_pton(AF_INET, "127.0.0.1", &servaddr.sin_addr) <= 0) { perror("inet_pton"); exit(EXIT_FAILURE); } // 连接服务器 if (connect(sockfd, (struct sockaddr *)&servaddr, sizeof(servaddr)) == -1) { perror("connect"); exit(EXIT_FAILURE); } // 发送数据 char *message = "Hello, world!"; if (send(sockfd, message, strlen(message), 0) == -1) { perror("send"); exit(EXIT_FAILURE); } // 接收数据 char buffer[1024]; int n; if ((n = recv(sockfd, buffer, sizeof(buffer) - 1, 0)) == -1) { perror("recv"); exit(EXIT_FAILURE); } buffer[n] = '\0'; printf("Received message: %s\n", buffer); // 关闭套接字 close(sockfd); return 0; } ``` 该程序通过创建套接字、连接服务器、发送数据、接收数据和关闭套接字等步骤实现TCP 套接字编程中的基本操作。其中,socket() 函数用于创建套接字,connect() 函数用于连接服务器,send() 函数用于发送数据,recv() 函数用于接收数据,close() 函数用于关闭套接字。 ### 回答2: TCP套接字是一种用于实现网络通信的协议。以下是一个简单的TCP套接字C语言代码示例: ```c #include <stdio.h> #include <stdlib.h> #include <string.h> #include <unistd.h> #include <arpa/inet.h> #define MAX_BUFFER_SIZE 1024 int main() { int serverSocket, clientSocket; struct sockaddr_in serverAddr, clientAddr; char buffer[MAX_BUFFER_SIZE]; // 创建套接字 if ((serverSocket = socket(AF_INET, SOCK_STREAM, 0)) == -1) { perror("套接字创建失败"); exit(EXIT_FAILURE); } // 设置服务器地址 serverAddr.sin_family = AF_INET; serverAddr.sin_addr.s_addr = inet_addr("127.0.0.1"); // 服务器IP地址 serverAddr.sin_port = htons(8888); // 服务器端口号 // 绑定套接字到服务器地址 if (bind(serverSocket, (struct sockaddr *)&serverAddr, sizeof(serverAddr)) == -1) { perror("绑定失败"); exit(EXIT_FAILURE); } // 监听连接 if (listen(serverSocket, 5) == -1) { perror("监听失败"); exit(EXIT_FAILURE); } printf("服务器等待客户端连接...\n"); // 接受客户端连接 socklen_t clientAddrLen = sizeof(clientAddr); if ((clientSocket = accept(serverSocket, (struct sockaddr *)&clientAddr, &clientAddrLen)) == -1) { perror("接受连接失败"); exit(EXIT_FAILURE); } printf("客户端连接成功\n"); // 接收和发送数据 while (1) { memset(buffer, 0, sizeof(buffer)); // 接收数据 if (recv(clientSocket, buffer, sizeof(buffer), 0) == -1) { perror("接收数据失败"); exit(EXIT_FAILURE); } printf("接收到客户端消息:%s\n", buffer); // 发送数据 if (send(clientSocket, buffer, strlen(buffer), 0) == -1) { perror("发送数据失败"); exit(EXIT_FAILURE); } if (strcmp(buffer, "quit\n") == 0) { break; } } // 关闭套接字 close(clientSocket); close(serverSocket); return 0; } ``` 这段代码演示了一个简单的TCP服务器,它创建了一个套接字,绑定到本地IP地址和端口8888,并监听连接。一旦有客户端连接成功,服务器将接收来自客户端的消息,并发送相同的消息回复客户端。如果接收到的消息是"quit\n",服务器将关闭连接。 ### 回答3: TCP套接字是一种用于在计算机网络中进行可靠通信的协议。下面是一个利用C语言编写的TCP套接字示例代码,用于在客户端和服务器之间进行通信。 (1)服务器端代码: ```C #include <stdio.h> #include <stdlib.h> #include <string.h> #include <sys/types.h> #include <sys/socket.h> #include <netinet/in.h> int main() { int sockfd, newsockfd, portno, clilen; char buffer[256]; struct sockaddr_in serv_addr, cli_addr; int n; sockfd = socket(AF_INET, SOCK_STREAM, 0); if (sockfd < 0) { perror("Error opening socket"); exit(1); } bzero((char *) &serv_addr, sizeof(serv_addr)); portno = 1234; serv_addr.sin_family = AF_INET; serv_addr.sin_addr.s_addr = INADDR_ANY; serv_addr.sin_port = htons(portno); if (bind(sockfd, (struct sockaddr *) &serv_addr, sizeof(serv_addr)) < 0) { perror("Error on binding"); exit(1); } listen(sockfd, 5); clilen = sizeof(cli_addr); newsockfd = accept(sockfd, (struct sockaddr *) &cli_addr, &clilen); if (newsockfd < 0) { perror("Error on accept"); exit(1); } bzero(buffer,256); n = read(newsockfd, buffer, 255); if (n < 0) { perror("Error reading from socket"); exit(1); } printf("Here is the message: %s\n",buffer); n = write(newsockfd,"I got your message",18); if (n < 0) { perror("Error writing to socket"); exit(1); } close(newsockfd); close(sockfd); return 0; } ``` (2)客户端代码: ```C #include <stdio.h> #include <stdlib.h> #include <string.h> #include <sys/types.h> #include <sys/socket.h> #include <netinet/in.h> #include <netdb.h> int main() { int sockfd, portno, n; struct sockaddr_in serv_addr; struct hostent *server; char buffer[256]; portno = 1234; sockfd = socket(AF_INET, SOCK_STREAM, 0); if (sockfd < 0) { perror("ERROR opening socket"); exit(1); } server = gethostbyname("localhost"); if (server == NULL) { perror("Error, no such host"); exit(1); } bzero((char *) &serv_addr, sizeof(serv_addr)); serv_addr.sin_family = AF_INET; bcopy((char *)server->h_addr, (char *)&serv_addr.sin_addr.s_addr, server->h_length); serv_addr.sin_port = htons(portno); if (connect(sockfd, (struct sockaddr *) &serv_addr, sizeof(serv_addr)) < 0) { perror("Error connecting"); exit(1); } printf("Please enter the message: "); bzero(buffer, 256); fgets(buffer, 255, stdin); n = write(sockfd, buffer, strlen(buffer)); if (n < 0) { perror("Error writing to socket"); exit(1); } bzero(buffer, 256); n = read(sockfd, buffer, 255); if (n < 0) { perror("Error reading from socket"); exit(1); } printf("%s\n",buffer); close(sockfd); return 0; } ``` 以上就是一个简单的TCP套接字C语言代码示例,用于在服务器端和客户端之间进行通信。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值