• TCP/IP Socket网络编程


    典型的Client/Server程序流程图

    面向流的套接字程序通常遵循规定的顺序。有关典型客户端和服务器的逻辑流程图,请参见下图。在研究此图时,请记住一个事实,即并发服务器通常在客户端启动之前启动,并在步骤3等待客户端请求连接。然后,在关闭客户端连接后,它将继续等待其他客户端请求。

    • 步骤1:服务器和客户端使用socket()调用创建一个流socket。
    • 步骤2 :(对于客户端是可选的)使用bind()调用将套接字s绑定到本地地址。
    • 步骤3:服务器使用listen()调用向TCP / IP机器发出接受连接意愿的警报。
    • 步骤4:客户端使用connect()调用将套接字s连接到外部主机。
    • 步骤5:服务器接受连接,并通过accept()阻塞,直到在此套接字上建立新连接例如ns或出现错误。
    • 步骤6和7:服务器使用send()和recv()调用在套接字ns上读取和写入数据,客户端在套接字s上读取和写入数据,直到所有数据都已交换。
    • 步骤8:服务器使用close()调用关闭套接字ns。客户端关闭套接字s,并通过close()调用结束TCP / IP会话。转到步骤5。

    Basic socket calls

    • Socket:获取一个要读取或写入的套接字。
    • Bind:将套接字与端口号关联。
    • Listen:告诉TCP⁄IP该进程正在侦听此套接字上的连接。
    • Select:等待套接字上的活动。
    • Accept:接受来自客户端的连接。
    • Connect:允许客户端打开与服务器端口的连接。

    C++ 网络编程实现:socket实现tcp和udp例子

    Server代码

    #include <stdio.h>
    #include <sys/types.h>
    #include <sys/socket.h>
    #include <netinet/in.h>
    #include <arpa/inet.h>
     
     
    int main(int argc, char *argv[])
    {
    	int server_sockfd;//服务器端套接字
    	int client_sockfd;//客户端套接字
    	int len;
    	struct sockaddr_in my_addr;   //服务器网络地址结构体
    	struct sockaddr_in remote_addr; //客户端网络地址结构体
    	int sin_size;
    	char buf[BUFSIZ];  //数据传送的缓冲区
    	memset(&my_addr,0,sizeof(my_addr)); //数据初始化--清零
    	my_addr.sin_family=AF_INET; //设置为IP通信
    	my_addr.sin_addr.s_addr=INADDR_ANY;//服务器IP地址--允许连接到所有本地地址上
    	my_addr.sin_port=htons(8000); //服务器端口号
    	
    	/*创建服务器端套接字--IPv4协议,面向连接通信,TCP协议*/
    	if((server_sockfd=socket(PF_INET,SOCK_STREAM,0))<0)
    	{  
    		perror("socket error");
    		return 1;
    	}
     
     
    	/*将套接字绑定到服务器的网络地址上*/
    	if(bind(server_sockfd,(struct sockaddr *)&my_addr,sizeof(struct sockaddr))<0)
    	{
    		perror("bind error");
    		return 1;
    	}
    	
    	/*监听连接请求--监听队列长度为5*/
    	if(listen(server_sockfd,5)<0)
    	{
    		perror("listen error");
    		return 1;
    	};
    	
    	sin_size=sizeof(struct sockaddr_in);
    	
    	/*等待客户端连接请求到达*/
    	if((client_sockfd=accept(server_sockfd,(struct sockaddr *)&remote_addr,&sin_size))<0)
    	{
    		perror("accept error");
    		return 1;
    	}
    	printf("accept client %s
    ",inet_ntoa(remote_addr.sin_addr));
    	len=send(client_sockfd,"Welcome to my server
    ",21,0);//发送欢迎信息
    	
    	/*接收客户端的数据并将其发送给客户端--recv返回接收到的字节数,send返回发送的字节数*/
    	while((len=recv(client_sockfd,buf,BUFSIZ,0))>0))
    	{
    		buf[len]='/0';
    		printf("%s
    ",buf);
    		if(send(client_sockfd,buf,len,0)<0)
    		{
    			perror("write error");
    			return 1;
    		}
    	}
     
     
    	/*关闭套接字*/
    	close(client_sockfd);
    	close(server_sockfd);
        
    	return 0;
    }
    

    Client代码

    #include <stdio.h>
    #include <sys/types.h>
    #include <sys/socket.h>
    #include <netinet/in.h>
    #include <arpa/inet.h>
     
    int main(int argc, char *argv[])
    {
    	int client_sockfd;
    	int len;
    	struct sockaddr_in remote_addr; //服务器端网络地址结构体
    	char buf[BUFSIZ];  //数据传送的缓冲区
    	memset(&remote_addr,0,sizeof(remote_addr)); //数据初始化--清零
    	remote_addr.sin_family=AF_INET; //设置为IP通信
    	remote_addr.sin_addr.s_addr=inet_addr("127.0.0.1");//服务器IP地址
    	remote_addr.sin_port=htons(8000); //服务器端口号
    	
    	/*创建客户端套接字--IPv4协议,面向连接通信,TCP协议*/
    	if((client_sockfd=socket(PF_INET,SOCK_STREAM,0))<0)
    	{
    		perror("socket error");
    		return 1;
    	}
    	
    	/*将套接字绑定到服务器的网络地址上*/
    	if(connect(client_sockfd,(struct sockaddr *)&remote_addr,sizeof(struct sockaddr))<0)
    	{
    		perror("connect error");
    		return 1;
    	}
    	printf("connected to server
    ");
    	len=recv(client_sockfd,buf,BUFSIZ,0);//接收服务器端信息
            buf[len]='/0';
    	printf("%s",buf); //打印服务器端信息
    	
    	/*循环的发送接收信息并打印接收信息(可以按需发送)--recv返回接收到的字节数,send返回发送的字节数*/
    	while(1)
    	{
    		printf("Enter string to send:");
    		scanf("%s",buf);
    		if(!strcmp(buf,"quit")
    			break;
    		len=send(client_sockfd,buf,strlen(buf),0);
    		len=recv(client_sockfd,buf,BUFSIZ,0);
    		buf[len]='/0';
    		printf("received:%s
    ",buf);
    	}
    	
    	/*关闭套接字*/
    	close(client_sockfd);
        
    	return 0;
    }
    
    
  • 相关阅读:
    Jmeter-日期格式转换为时间戳
    Java中异常的处理
    Java中接口的新特性,为接口添加静态方法和默认方法
    Java接口的应用之代理模式
    Java之接口(interface)的理解
    JAVA中使用super调用属性、方法、构造器
    JAVA方法的重写
    Java之方法
    Java之匿名对象
    关于多态性的使用
  • 原文地址:https://www.cnblogs.com/lyszyl/p/12460582.html
Copyright © 2020-2023  润新知