TCP——网络编程

一、TCP服务器编写流程

服务器:
            创建套接字 socket()
            将套接字与服务器网络信息结构体绑定 bind()
            将套接字设置为监听状态 listen()
            阻塞等待客户端的连接请求 accept()
           进行通信 recv()/send()
           关闭套接字 close()

二、TCP编程——socket函数

头文件

                #include <sys/types.h>
                #include <sys/socket.h>
函数:
              int socket(int domain, int type, int protocol);
功能:

             创建一个套接字,返回一个文件描述符
参数:
            domain:通信域,协议族
                           AF_UNIX 本地通信 

                           AF_INET ipv4网络协议
                           AF_INET6 ipv6网络协议
                           AF_PACKET 底层接口
                 type :套接字的类型
                           SOCK_STREAM 流式套接字(tcp)
                           SOCK_DGRAM 数据报套接字(udp)
                           SOCK_RAW 原始套接字(用于链路层)
           protocol:附加协议,如果不需要,则设置为0
返回值:
              成功:文件描述符
              失败:‐1

三、 TCP编程——bind函数

头文件:

             #include <sys/types.h>
             #include <sys/socket.h>
函数;

            int bind(int sockfd, const struct sockaddr *addr, socklen_t addrlen);
功能:

            将套接字与网络信息结构体绑定
参数:
            sockfd:文件描述符,socket的返回值
               addr:网络信息结构体 
        struct sockaddr    通用结构体(一般不用)
             sockaddr_in    常用网络信息结构体
            addrlen:addr的长度
返回值:
            成功:0
            失败:‐1

          sockaddr_in    常用网络信息结构体

头文件:

                #include <netinet/in.h>

 函数结构体:

 
         struct sockaddr_in
    {
        sa_family_t sin_family;            //协议族 2字节
        in_port_t sin_port;                    //端口号 2字节
        struct in_addr sin_addr;       //ip地址 4字节
        char sin_zero[8]                       //填充,不起什么作用 8字节
          };

   struct in_addr
      {
      in_addr_t s_addr;                       //ip地址 4字节
             };
 

示例:


unsigned short port =8080;
 
struct sockaddr_in mysockaddr;


mysockaddr.sin_family = AF_INET;

mysockaddr.sin_port = htons(port);

mysockaddr.sin_addr.s_addr = htonl(INADDR_ANY);


if(bind(sockfd,(struct sockaddr *)&mysockadrr,sizeof(mysockaddr)==-1)
{

     perror("fail to bind");
     exit(1);
 
   }

四、 TCP编程——listen函数

头文件:
             #include <sys/types.h> 
             #include <sys/socket.h>
函数:

             int listen(int sockfd, int backlog);
功能:

            将套接字设置为被动监听状态,这样做之后就可以接收到连接请求
参数:
              sockfd:文件描述符,socket函数返回值
             backlog:允许同时通信连接的主机个数,一般设置为5、10
返回值:
             成功:0
             失败:‐1

 五、TCP编程——accept函数

头文件:

            #include <sys/types.h> 
            #include <sys/socket.h>
函数:

          int accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen);
功能:阻塞等待客户端的连接请求
参数:
            sockfd:文件描述符,socket函数的返回值
                addr:接收到的客户端的信息结构体(自动填充,定义变量即可)
           addrlen:addr的长度
 返回值:
                成功:新的文件描述符(只要有客户端连接,就会产生新的文件描述符,
               这个新的文件描述符专门与指定的客户端进行通信的)
 失败:‐1

 注意:返回的是一个已连接套接字,这个套接字代表当前这个连接

5.1、分析功能

六、TCP服务器代码实现并且(与上一节TCP客户端)通信

6.1、简单的服务器代码

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

 int main(int argc ,char *argv[])
 {
	 
      if(argc <3)
	  {
		  printf("error: lose ip port\n");
		  exit(1);
		  
		  }

	  int sockfd ;

	  if((sockfd=socket(AF_INET,SOCK_STREAM,0))==-1)
	  {
		   perror("fail to sockfd");
		   exit(1);
		    }
     struct sockaddr_in mysockaddr;

	 mysockaddr.sin_family=AF_INET;
     mysockaddr.sin_port=htons(atoi(argv[2]));
	 mysockaddr.sin_addr.s_addr=htonl(INADDR_ANY);
     socklen_t addrlen = sizeof(mysockaddr);

	   if(bind(sockfd,(struct sockaddr*)&mysockaddr,addrlen)==-1)
	{
		 perror("fail to bind");
		 exit(1);
		 
		 }
	     
       if(listen(sockfd,10)==-1)
	   {
		   perror("fail to listen");
		   exit(1);
		    }
	 int acceptfd;
     struct sockaddr_in acceptaddr;
     socklen_t acceptlen=sizeof(acceptaddr);

	 if((acceptfd= accept(sockfd,(struct sockaddr *)&acceptaddr,&acceptlen))==-1)
	 {
		 perror("fail to acceptfd");
		 exit(1);
		   
		    }
	  
	  char buf[128]="";
      char text[128]="";
	  if(recv(acceptfd,buf,128,0)==-1)
	  {
		perror("fail to recv");
		exit(1);
		  
		  }
	 
  printf("ip=%s,port=%d\n",inet_ntoa(acceptaddr.sin_addr),ntohs(acceptaddr.sin_port));

  printf("%s\n",buf) ;

      strcat(text, " *_*");

       if(send(acceptfd,text,128,0)==-1)
	   {
		   perror("fail to send");
		   exit(1);
		   
		   }	 
	 close(acceptfd);
	 close(sockfd);
	   return 0;
	      }

6.2、简单的客户端代码

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


#define N 1024
int main(int argc ,char *argv[])
{
	 if(argc<3)
	 {
		 printf("fail ,lose ip port\n");
		 exit(1);
		 
		 }
	 int sockfd;

	 if((sockfd=socket(AF_INET,SOCK_STREAM,0))==-1)
	 {
		 perror("fail to sockfd");
		 exit(1);
		 
		 }

//	  printf("TCP:sockfd= %d\n",sockfd);
        
      struct sockaddr_in mysockaddr;

	  mysockaddr.sin_family=AF_INET;
	  mysockaddr.sin_port=htons(atoi(argv[2]));
	  mysockaddr.sin_addr.s_addr=inet_addr(argv[1]);
	  socklen_t addrlen= sizeof(mysockaddr);

      if(connect(sockfd,(struct sockaddr*)&mysockaddr,addrlen)==-1)
	  {
		   perror("fail to connect");
		   exit(1);
		   }
	   
	  
	     char buf[N]="";		 
		
		  fgets(buf,N,stdin);
          
		  if(send(sockfd,buf,N,0)==-1)
		  {
			  perror("fail to send");
			  exit(1);
			  
			  }
		  
	     char text[500]="";
		 if(recv(sockfd,text,50,0)==-1)
		 {
	          perror("fail to recv");
			  exit(1);

			 }
		  
		  printf("from server: %s\n",text);
	    	  
         		  
		  close(sockfd);
	  
        	return 0;
	
	}

运行结果

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值