TCP编程:流的封包和解包

Posted 栀子花开

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了TCP编程:流的封包和解包相关的知识,希望对你有一定的参考价值。

刚给linux扩容,不用再担心 开发机的磁盘空间了

服务器:

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

int MyRecv( int iSock, char * pchBuf, size_t tCount){
        size_t tBytesRead=0;
        int iThisRead;
        while(tBytesRead < tCount){
              do{
                     iThisRead = read(iSock, pchBuf, tCount-tBytesRead);
              } while((iThisRead<0) && (errno==EINTR));
              if(iThisRead < 0){
                      return(iThisRead);
              }else if (iThisRead == 0)
                      return(tBytesRead);
              tBytesRead += iThisRead;
              pchBuf += iThisRead;
       }
}
#define DEFAULT_PORT 6666
int main( int argc, char ** argv){
    int sockfd,acceptfd; /* 监听socket: sock_fd,数据传输socket: acceptfd */
    struct sockaddr_in my_addr; /* 本机地址信息 */
    struct sockaddr_in their_addr; /* 客户地址信息 */
    unsigned int sin_size, myport=6666, lisnum=10;
    if ((sockfd = socket(AF_INET , SOCK_STREAM, 0)) == -1) {
       perror("socket" );
       return -1;
    }
    printf("socket ok \\n");
    my_addr.sin_family=AF_INET;
    my_addr.sin_port=htons(DEFAULT_PORT);
    my_addr.sin_addr.s_addr = INADDR_ANY;
    bzero(&(my_addr.sin_zero), 0);
    if (bind(sockfd, (struct sockaddr *)&my_addr, sizeof(struct sockaddr )) == -1) {
        perror("bind" );
        return -2;
    }
    printf("bind ok \\n");
    if (listen(sockfd, lisnum) == -1) {
        perror("listen" );
        return -3;
    }
    printf("listen ok \\n");
    char recvMsg[10];
    sin_size = sizeof(my_addr);
    acceptfd = accept(sockfd,(struct sockaddr *)&my_addr,&sin_size);
    if (acceptfd < 0) {
       close(sockfd);
       printf("accept failed\\n" );
       return -4;
    }
    ssize_t readLen = MyRecv(acceptfd, recvMsg, sizeof( int));
    if (readLen < 0) {
       printf("read failed\\n" );
       return -1;
    }
    int len=( int)ntohl(*( int*)recvMsg);
    printf("len:%d\\n",len);
    readLen = MyRecv(acceptfd, recvMsg, len);
    if (readLen < 0) {
       printf("read failed\\n" );
       return -1;
    }
    recvMsg[len]=\'\\0\';
    printf("recvMsg:%s\\n" ,recvMsg);
    close(acceptfd);
    return 0;
  }

客户端:

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

int main(int argc, char** argv){
    int   sockfd, n;
    char  recvline[4096], sendline[4096];
    struct sockaddr_in  servaddr;

    if( argc != 2){
        printf("usage: ./client <ipaddress>\\n");
        return 0;
    }

    if( (sockfd = socket(AF_INET, SOCK_STREAM, 0)) < 0){
        printf("create socket error: %s(errno: %d)\\n", strerror(errno),errno);
        return 0;
    }

    memset(&servaddr, 0, sizeof(servaddr));
    servaddr.sin_family = AF_INET;
    servaddr.sin_port = htons(6666);
    if( inet_pton(AF_INET, argv[1], &servaddr.sin_addr) <= 0){
        printf("inet_pton error for %s\\n",argv[1]);
        return 0;
    }

    if( connect(sockfd, (struct sockaddr*)&servaddr, sizeof(servaddr)) < 0){
        printf("connect error: %s(errno: %d)\\n",strerror(errno),errno);
        return 0;
    }

    printf("send msg to server: \\n");
    fgets(sendline, 4096, stdin);
    if( send(sockfd, sendline, strlen(sendline), 0) < 0){
        printf("send msg error: %s(errno: %d)\\n", strerror(errno), errno);
        return 0;
    }
    close(sockfd);
    return 0;
}

 

以上是关于TCP编程:流的封包和解包的主要内容,如果未能解决你的问题,请参考以下文章

关于防止内存泄漏的封包和解包

[Go] 轻量服务器框架tcp的粘包问题 封包与拆包

pythonsocket编程3

Python—socket编程和黏包问题

求助,求python关于socket协议打包和解包相关方法

Netty——解决TCP粘包、拆包