linux网络编程--TCP/IP协议

来源:互联网 发布:玩数码频道淘宝 编辑:程序博客网 时间:2024/05/16 20:29

特点

  1. TCP协议的位于数据传输层,其上一层是应用层,因此其目的是为了实现一个应用于另一个应用之间数据传输。

  2. TCP协议需要进行三次握手实现数据发送和接收的同步。

    第一次握手:客户端向服务端提出连接请求。这时TCP SYN标 志置位。客户端告诉服务端序列号区域合法,需要检查。客户端 在TCP报头的序列号区中插入自己的ISN。服务端收到该TCP分 段后,。
    第二次握手:接收主机通过发回具有以下项目的数据段表示回 复:同步标志置位、即将发送的数据段的起始字节的顺序号、应 答并带有将收到的下一个数据段的字节顺序号
    第三次握手:客户端确认收到服务端的ISN(ACK标志置位)。到此为止建立完整的TCP连接,开始全双工模式的数据传输过程。

实现过程

1.客户端程序

#include<stdio.h>#include <sys/types.h>          /* See NOTES */#include <sys/socket.h>#include <netinet/in.h>#include <netinet/ip.h> /* superset of previous */#include <arpa/inet.h>#include <stdlib.h>#include <signal.h>#include <string.h>#define BUF_SIZE 512/**********************所用到的函数*******************************int socket(int domain, int type, int protocol);  创建套接字函数AF_INET  IPV4协议   SOCK_STREAM 流套接字int bind(int sockfd, const struct sockaddr *addr,socklen_t addrlen);结构体sockaddr的成员 struct sockaddr {           sa_family_t sa_family;           char        sa_data[14]; }struct sockaddr_in {           sa_family_t    sin_family; /* address family: AF_INET            in_port_t      sin_port;   /* port in network byte order           struct in_addr sin_addr;   /* internet address        };struct in_addr {           uint32_t       s_addr;     /* address in network byte order        };   int listen(int sockfd, int backlog);   sighandler_t signal(int signum, sighandler_t handler);   int accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen);   int connect(int sockfd, const struct sockaddr *addr,socklen_t addrlen);   char *fgets(char *s, int size, FILE *stream);//接收终端输入文件流    ********************************************************/int main(){int client_id;struct sockaddr_in clientadd;char buffer[BUF_SIZE];client_id=socket(AF_INET,SOCK_STREAM,0);  //创建套接字clientadd.sin_family=AF_INET;   //结构体成员赋值clientadd.sin_port=htons(9736);//指定端口号clientadd.sin_addr.s_addr=inet_addr("192.168.1.121"); //绑定IP地址,此处的IP为服务器IPif(connect(client_id,(struct sockaddr *)&clientadd,sizeof(clientadd))==-1)//创建连接{    //链接失败    printf("connect   failed!\n");    exit(EXIT_FAILURE);}printf("please input:");fgets(buffer,BUF_SIZE,stdin);//向服务器写write(client_id,buffer,BUF_SIZE);//将获取的数据发送至缓冲区sleep(rand()%3);memset(buffer,0,strlen(buffer));read(client_id,buffer,BUF_SIZE);//接收返回数据printf("You input:%s\n",buffer);close(client_id);return 0;}

2.服务器程序

服务器程序主要实现从客户端接收数据,将接收到的数据返回给客户端。

#include<stdio.h>#include <sys/types.h>          /* See NOTES */#include <sys/socket.h>#include <netinet/in.h>#include <netinet/ip.h> /* superset of previous */#include <arpa/inet.h>#include <stdlib.h>#include <signal.h>#include <string.h>#define BUF_SIZE 512/********用到的函数************************int socket(int domain, int type, int protocol);  创建套接字AF_INET  IPV4协议   SOCK_STREAMint bind(int sockfd, const struct sockaddr *addr,socklen_t addrlen);   struct sockaddr {           sa_family_t sa_family;           char        sa_data[14];       }   struct sockaddr_in {           sa_family_t    sin_family; /* address family: AF_INET            in_port_t      sin_port;   /* port in network byte order           struct in_addr sin_addr;   /* internet address        };   struct in_addr {           uint32_t       s_addr;     /* address in network byte order        };   int listen(int sockfd, int backlog);   sighandler_t signal(int signum, sighandler_t handler);   int accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen);    ********************************************************/int main(){int socket_id,client_id;struct sockaddr_in serveradd;struct sockaddr_in clientadd;int clientlen;char buffer[BUF_SIZE+1];socket_id=socket(AF_INET,SOCK_STREAM,0);  //创建套接字serveradd.sin_family=AF_INET;serveradd.sin_port=htons(9736);//指定端口好serveradd.sin_addr.s_addr=htonl(INADDR_ANY); //绑定IP地址    这里指定监听的IP地址是任何一个访问的IPif(bind(socket_id,(struct sockaddr *)&serveradd,sizeof(serveradd))==-1){    //绑定失败    printf("connect   failed!\n");    exit(EXIT_FAILURE);}//服务器端需要绑定端口和IP,服务器端需要对固定的端口和指定的IP进行监听,因此需要进行bind操作,而客户端部分不需要listen(socket_id,5);//最大允许5个客户端访问signal(SIGCHLD,SIG_IGN);while(1){    clientlen=sizeof(clientadd);    printf("please waiting....\n");    client_id=accept(socket_id,(struct sockaddr *)&clientadd,&clientlen);//监听zijincheng    if(fork()==0)//新建一个子进程,在子进程中实现接收客户端发送过来的内容并将其发送回去,同时显示在终端上。    {        read(client_id,buffer,BUF_SIZE);        buffer[BUF_SIZE]='\0';        printf("You input :%s\n",buffer);        sleep(rand()%3);        write(client_id,buffer,BUF_SIZE);        close(client_id);        exit(EXIT_SUCCESS);    }    else    {        close(client_id);//关闭子进程    }}}
0 0
原创粉丝点击