zoukankan      html  css  js  c++  java
  • TCP编程的一个小例子

    TCP程序的服务器端与客户端的流程图

    例子:服务器端等待客户端连接,若连接成功,则用户可以通过客户端向服务器端发送任意字符串,服务器端在收到字符串后,输出相关信息,在把接受到的字符串重新发生给客户端。客户端收到后显示在屏幕上

    服务器端:

    #include <sys/stat.h>
    #include <fcntl.h>
    #include <errno.h>
    #include <netdb.h>
    #include <sys/types.h>
    #include <sys/socket.h>
    #include <netinet/in.h>
    #include <arpa/inet.h>
    #include <string.h>
    #include <stdlib.h>
    #include <stdio.h>
    #include <unistd.h>
    
    #define SERVER_PORT 5555
    
    int main()
    {
    	int serverSocket;
    	struct sockaddr_in server_addr;
    	struct sockaddr_in clientAddr;
    	int addr_len = sizeof(clientAddr);
    	int client;
    	char buffer[1024];
    	int iDataNum;
    
    	//创建服务器端套接字,SOCK_STREAM指的是TCP通信,面向连接的字节流;SOCK_DGRAM是指UDP通信
    	if ((serverSocket = socket(AF_INET, SOCK_STREAM, 0)) < 0)	//创建服务器端套接字,返回值为套接字号
    	{
    		perror("socket");
    		exit(1);
    	}
    
    	bzero(&server_addr, sizeof(server_addr));
    //	memset(server_addr, 0, sizeof(server_addr));
    	server_addr.sin_family = AF_INET;				//AF_INET用来指定当前采用的协议是TCP/IP
    	server_addr.sin_port = htons(SERVER_PORT);		//htons()用于字节序的转换,表示将一个数值从主机字节序转换成网络字节序,保证数据的一致性
    	server_addr.sin_addr.s_addr = htonl(INADDR_ANY);//htons()函数是指16字节的转换,htonl()是32字节序转换
    	if (bind(serverSocket, (struct sockaddr *)&server_addr, sizeof(server_addr)) < 0)	//将地址信息与此前创建成功的套接字关联在一起
    	{
    		perror("connect");
    		exit(1);
    	}
    
    	if (listen(serverSocket, 5) < 0)	//服务套接字在指定端口监听,以被动的方式等待客户端连接,其中5为请求连接队列的最大长度
    	{
    		perror("listen");
    		exit(1);
    	}
    
    	while (1)
    	{
    		//accept()函数主要是在指定的端口侦听,当客户端的连接请求到来时,维护并完成通信连接的建立,然后在这条链路上进行数据的收发
    		//第一个参数为当前服务套接字,第二个参数用于保存当前客户端的地址信息,第三个参数为客户端地址的长度
    		client = accept(serverSocket, (struct sockaddr *)&clientAddr, (socklen_t *)&addr_len);
    		if (client < 0)
    		{
    			perror("accept");
    			continue;
    		}
    		iDataNum = read(client, buffer, 1024);
    		buffer[iDataNum] = '';
    		if (iDataNum < 0)
    		{
    			perror("recv");
    			continue;
    		}
    		printf("
    Recv client data...
    ");
    		printf("IP is %s
    ", inet_ntoa(clientAddr.sin_addr));
    		printf("Port is %d
    ", htons(clientAddr.sin_port));
    		printf("Recv Data is %s, the data length is %d
    ", buffer, iDataNum);
    		write(client, buffer, iDataNum);
    	}
    	return 0;
    }


    客户端:

    #include <sys/stat.h>
    #include <fcntl.h>
    #include <errno.h>
    #include <netdb.h>
    #include <sys/types.h>
    #include <sys/socket.h>
    #include <netinet/in.h>
    #include <arpa/inet.h>
    #include <string.h>
    #include <stdlib.h>
    #include <stdio.h>
    #include <unistd.h>
    
    int main()
    {
    	int len;
    	struct sockaddr_in serverAddr;
    	int clientSocket;
    	char sendbuf[200];
    	char recvbuf[200];
    	if ((clientSocket = socket(AF_INET, SOCK_STREAM, 0)) < 0)
    	{
    		perror("socket error");
    		return -1;
    	}
    
    	serverAddr.sin_family = AF_INET;
    	serverAddr.sin_port = htons(5555);
    	serverAddr.sin_addr.s_addr = inet_addr("127.0.0.1");
    	//connect()函数帮助客户端向指定地址的服务器发起一条TCP连接,成功返回0;第一个参数为连接套接字,第二个为服务器端的地址信息和协议信息
    	if (connect(clientSocket, (struct sockaddr *)&serverAddr, sizeof(serverAddr)) < 0)
    	{
    		perror("connect");
    		exit(1);
    	}
    	printf("connect with destination host...
    ");
    	while (1)
    	{
    		printf("Input your Word:>");
    		scanf("%s", sendbuf);		//缺陷:不能传输带空格的句子
    		printf("
    ");
    
    		if (strcmp(sendbuf, "quit") == 0)
    			break;
    		
    		write(clientSocket, sendbuf, strlen(sendbuf));
    		len = read(clientSocket, recvbuf, 200);
    		recvbuf[len] = '';
    		printf("recv data of my word is : %s
    ", recvbuf);
    	}
    	close(clientSocket);
    
    	return 0;
    }


    注:有个小问题是为什么客户端不能循环输入?


    UDP即无链接编程,和这个类似,一般用在P2P中,主要是创建socket的时候,要指定SOCK——DGRAM.

    数据的收发调用sendto()和recvfrom().

  • 相关阅读:
    给元素查索引
    数组的反转和排序
    本地修改文件到git
    +new Date()
    文字双层投影
    表格组件 自定义宽度 设置 span 内容 超出省略号
    iframe的使用
    分页获取列表进行索引累加
    日期时间格式化
    柱状echarts 自定义图例设置
  • 原文地址:https://www.cnblogs.com/keanuyaoo/p/3293844.html
Copyright © 2011-2022 走看看