基于c语言的TCP客户端、服务端基础代码

基于c语言的TCP客户端、服务端基础代码

基本流程:

image

  1. 客户端:
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <stdio.h>
#include <errno.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netinet/ip.h>
#include <arpa/inet.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netinet/udp.h>
#include <stdlib.h>
#include <string.h>
#include <sys/socket.h>
#include <unistd.h>

/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
*
*   tcp客户端(发送)
*
*
*
*
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
int main(int argc, char *argv[])
{

    int sockfd = socket(AF_INET, SOCK_STREAM, 0);

    struct sockaddr_in addr;
    addr.sin_family = AF_INET;             // 协议族,是固定的
    addr.sin_port = htons(atoi(argv[1]));  // 服务器端口,必须转换为网络字节序
    addr.sin_addr.s_addr = inet_addr(argv[2]); // 服务器地址 "192.168.64.xxx"

    connect(sockfd, (struct sockaddr *)&addr, sizeof(addr));

    char sendbuff[100];
    char recvbuff[100];

    while (1)
    {
        bzero(sendbuff, 100);
        scanf("%s",sendbuff);
        // fgets(sendbuff, 100, stdin);

        // 向服务端发送数据
        write(sockfd, sendbuff, strlen(sendbuff));
        //还可以使用send、sendto、sendmsg、

        // 接收TCP回弹服务器的消息
        
        printf("收到消息recvbuff = %s\n", recvbuff);
        bzero(recvbuff, 100);
    }
    close(sockfd);
    return 0;
}
  1. 服务端:


#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <stdio.h>
#include <errno.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netinet/ip.h>
#include <arpa/inet.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netinet/udp.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
 #include <unistd.h>
//TCP服务器代码   ./xxx   port

/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
*
*   tcp服务端(接收)
*
*
*
*
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
int main(int argc, char const *argv[])
{
	//1.创建TCP套接字
	int tcp_socket = socket(AF_INET, SOCK_STREAM, 0);
	if (tcp_socket == -1)
	{
		fprintf(stderr, "tcp socket error,errno:%d,%s\n",errno,strerror(errno));
		exit(1);
	}

	//2.绑定自身的IP地址和端口
	struct sockaddr_in  host_addr;

	host_addr.sin_family 		= AF_INET; 						//协议族,是固定的
	host_addr.sin_port   		= htons(atoi(argv[1]));			//目标端口,必须转换为网络字节序
	host_addr.sin_addr.s_addr   = htonl(INADDR_ANY);		    //目标地址  INADDR_ANY 这个宏是一个整数,所以需要使用htonl转换为网络字节序

	bind(tcp_socket,(struct sockaddr *)&host_addr, sizeof(host_addr));

	//3.设置监听  队列最大容量是5
	listen(tcp_socket,5);

	//4.等待接受客户端的连接请求
	struct sockaddr_in  client;
	socklen_t client_len = sizeof(client);

	int connect_fd = accept(tcp_socket,(struct sockaddr *)&client,&client_len); //会阻塞
	char buf[128] = {0};

	//5.说明双方建立连接,此时可以接收数据
	while(1)
	{
		
		
		read(connect_fd,buf,sizeof(buf));
		printf("recv from [%s],data is = %s\n", inet_ntoa(client.sin_addr) ,buf);
		bzero(buf,sizeof(buf));
	}


	return 0;
}
  1. 三次握手示意图:
    image

  2. 示意图解释:

第一次握手:发送一个SYN标记(请求同步标记)

​ 发送一个序列号seq:x

第二次握手:返回一个SYN标记

​ 返回一个ACK(应答标记,表示我知道了)

​ 返回一个序列号seq:y

​ 返回一个x+1序列号ack(告诉客户端希望下一次数据从+1开始)

第三次握手:发送一个ACK标记

​ 发送一个序列号seq:x+1

​ 发送一个序列号ack:y+1

posted @ 2024-06-05 20:04  周半仙  阅读(490)  评论(0)    收藏  举报