1. 程式人生 > 其它 >TCP資料讀寫

TCP資料讀寫

技術標籤:Linux學習

服務端的程式testoobrecv.c

#include<sys/socket.h>
#include<netinet/in.h>
#include<arpa/inet.h>
#include<signal.h>
#include<unistd.h>
#include<stdlib.h>
#include<assert.h>
#include<stdio.h>
#include<errno.h>
#include<string.h>
#include<stdbool.h>
#include<libgen.h>
const int BUF_SIZE=1024;
int main(int argc,char* argv[])
{
    if(argc<=2)
    {
        printf("usage: %s ip_address port_number\n",basename(argv[0]));
        return 1;
    }
    const char* ip=argv[1];
    int port=atoi(argv[2]);

    int sock=socket(PF_INET,SOCK_STREAM,0);
    assert(sock>=0);

    // 建立一個ipv4地址
    struct sockaddr_in address;
    bzero(&address,sizeof(address));
    address.sin_family=AF_INET;
    inet_pton(AF_INET,ip,&address.sin_addr);
    address.sin_port=htons(port);

    int  ret=bind(sock,(struct sockaddr*)&address,sizeof(address));
    assert(ret!=-1);

    ret=listen(sock,5);
    assert(ret!=-1);

    struct sockaddr_in client;
    socklen_t client_addrlength=sizeof(client);
    int connfd=accept(sock,(struct sockaddr*)&client,&client_addrlength);
    if(connfd<0)
    {
        printf("errno is: %d\n",errno);
    }
    else
    {
        char buffer[BUF_SIZE];

        memset(buffer,'\0',BUF_SIZE);
        ret=recv(connfd,buffer,BUF_SIZE-1,0);
        printf("got %d bytes of normal data %s\n",ret,buffer);

        memset(buffer,'\0',BUF_SIZE);
        ret=recv(connfd,buffer,BUF_SIZE-1,MSG_OOB);
        printf("got %d bytes of normal data %s\n",ret,buffer);

        memset(buffer,'\0',BUF_SIZE);
        ret=recv(connfd,buffer,BUF_SIZE-1,0);
        printf("got %d bytes of normal data %s\n",ret,buffer);

        close(connfd);
    }

    close(sock);
    return 0;
}

客戶端C語言版本如下,但我沒裝Linux虛擬機器,我用Python代替的。

C語言版本如下:

#include<sys/socket.h>
#include<netinet/in.h>
#include<arpa/inet.h>
#include<signal.h>
#include<unistd.h>
#include<stdlib.h>
#include<assert.h>
#include<stdio.h>
#include<errno.h>
#include<string.h>
#include<stdbool.h>
#include<libgen.h>
int main(int argc,char* argv[])
{
    if(argc<=2)
    {
        printf("usage: %s ip_address port_number\n",basename(argv[0]));
        return 1;
    }
    const char* ip=argv[1];
    int port=atoi(argv[2]);

    int sockfd=socket(PF_INET,SOCK_STREAM,0);
    assert(sockfd>=0);

    // 建立一個ipv4地址
    struct sockaddr_in server_address;
    bzero(&server_address,sizeof(server_address));
    server_address.sin_family=AF_INET;
    inet_pton(AF_INET,ip,&server_address.sin_addr);
    server_address.sin_port=htons(port);

    if(connect(sockfd,(struct sockaddr*)&server_address,sizeof(server_address))<0)
    {
        printf("connection failed\n");
    }
    else
    {
        const char* oob_data="abc";
        const char* normal_data="123";
        send(sockfd,normal_data,strlen(normal_data),0);
        send(sockfd,oob_data,strlen(oob_data),0);
        send(sockfd,normal_data,strlen(normal_data),0);
    }
    close(sockfd);
    return 0;
}

Python版本如下:

import socket
import sys
 
HOST='42.192.230.82'
PORT=6000
MESSAGE='UDP伺服器,你好![握手中...]'
 
if __name__=='__main__':
    try:
        sock=socket.socket(socket.AF_INET,socket.SOCK_STREAM)
    except socket.error as err:
        print('建立socket例項失敗')
        print('原因:%s'%str(err))
        sys.exit()
    print(u'socket例項建立成功!')
    try:
        sock.connect((HOST,int(PORT)))
        print('socket已經連線上目標主機:%s,連線的目標主機埠:%s'%(HOST,PORT))
        sock.sendto(MESSAGE.encode(),(HOST,PORT))
        sock.shutdown(2)
    except socket.error as err:
        print(u'連線主機:%s埠:%s失敗'%(HOST,PORT))
        print('原因:%s'%str(err))
    sys.exit();

伺服器端執行如下:

客戶端

後來一想,可以在伺服器上同時執行服務端程式和客戶端程式嘛,反正效果一樣。