LinuxQuestions.org

LinuxQuestions.org (/questions/)
-   Programming (https://www.linuxquestions.org/questions/programming-9/)
-   -   Unix socket programming - how to sent a file (https://www.linuxquestions.org/questions/programming-9/unix-socket-programming-how-to-sent-a-file-163455/)

Scrag 03-28-2004 04:24 PM

Unix socket programming - how to sent a file
 
Hi,

I've been studying socket programming for unix, but Im having trouble figuring out how to send a file accross the socket. Just the real basics for starters, could someone give me an example of this, where say, someone connects on port 3490 of server, then server just sends them back a file. Or if you know the location of any tutorials that would be cool too.

Thanks!

:Pengy:

Chris_tt 03-28-2004 05:01 PM

Hi,

UNIX network programming, Volume1 Networking APIs. W. Richard Stevens

all the sources from this book on: http://www.kohala.com/start/

Best regards,
Chris

infamous41md 03-28-2004 05:11 PM

client
Code:

#include <my_sock.h>
#include <sys/stat.h>

#define PORT 6969
#define BUFSIZE 8192

int main(int argc, char **argv)
{
    int    sock = 0, fd = 0, sendret = 0, nread = 0;
    char    buf[BUFSIZE];
    struct  sockaddr_in servaddr;
    struct stat    statbuf;

    if (argc != 3){
        printf("Usage: %s <server ip> <file>\n", argv[0]);
        return 1;
    }

    //initialize the socket -- returns < 0 on error
    if ( (sock = socket(AF_INET, SOCK_STREAM, 0)) < 0)
        err_quit("socket");

    //open the file
    if( (fd = open(argv[2], O_RDONLY)) < 0)
        err_quit("open");

    //setup the sock_addrin structure
    memset(&servaddr, 0, sizeof(servaddr));
    servaddr.sin_family = AF_INET;
    servaddr.sin_port  = htons(PORT);
    servaddr.sin_addr.s_addr = inet_addr(argv[1]);

    //connect to the server, returns < 0 on error
    if (connect(sock, (struct sockaddr *) &servaddr, sizeof(servaddr)) < 0)
        err_quit("connect");

    //send the file
    while( (nread = read(fd, buf, BUFSIZE)) > 0)
        if(write(sock, buf, nread) < 0)
            err_quit("write");

    close(fd);
    close(sock);

    return 0;
}

server
Code:

#include <mlib/my_sock.h>
#include <errno.h>
   
#define PORT 6969
#define BUFSIZE 8192
#define PERM (S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH)
#define MAXTHREADS 25

void * f00(void *data)

    char    buf[BUFSIZE];
    int asock = (int) data, nread = 0, fd = 0;
   
    //open the file
    if( (fd = open("tmp", O_CREAT | O_TRUNC | O_WRONLY, PERM)) < 0)
        err_quit("open");
   
    //read from socket, write to file
    while( (nread = read(asock, buf, BUFSIZE)) > 0)
        if(write(fd, buf, nread) != nread)
            err_quit("write");
       
    close(fd);
    return;
};         

int main(int argc, char **argv)
{     
    u_int  rbufsz = 64000;
    int    on = 1, fd = 0, lsock = 0, asock = 0, nread = 0, nthreads = 0, x = 0;
    char    buf[BUFSIZE];
    struct  sockaddr_in sa, csa;
    struct in_addr  *inptr = NULL;
    socklen_t len = sizeof(sa);
    pthread_t  threadid[MAXTHREADS];
   
    //initialize the socket -- returns < 0 on error
    if ( (lsock = socket(AF_INET, SOCK_STREAM, 0)) < 0)
        perr_quit("socket");
   
    if(setsockopt(lsock, SOL_SOCKET, SO_RCVBUF, &rbufsz, sizeof(rbufsz)) != 0)
        perr_quit("setsockopt");
   
    if(setsockopt(lsock, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on)) < 0)
        perr_quit("setsockopt");

    //setup the sock_addrin structure
    memset(&sa, 0, sizeof(sa));
    memset(&csa, 0, sizeof(csa));
    sa.sin_family = AF_INET;
    sa.sin_port  = htons(PORT);   
    sa.sin_addr.s_addr = htonl(INADDR_ANY);
   
    //bind socket
    if( (bind(lsock, (struct sockaddr *) &sa, sizeof(sa))) < 0)
        err_quit("bind");
   
    //go into listen mode
    if( (listen(lsock, 5)) < 0)
        err_quit("listen");
   
    while(1){
        //accept a connection
        if( (asock = accept(lsock, (struct sockaddr *)&csa, &len)) < 0)
            perr_quit("accept");
       
        printf("address is %d.%d.%d.%d\n", NIPQUAD(csa.sin_addr.s_addr) );
       
        if(setsockopt(lsock, SOL_SOCKET, SO_RCVBUF, &rbufsz, sizeof(rbufsz)) != 0)
            perr_quit("setsockopt");
       
        //spawn a thread for each clien
        if(pthread_create(&threadid[x++], NULL, (void *)&f00, (int)asock) != 0)
            perr_quit("pthread");
       
        if(nthreads++ >= MAXTHREADS)
            break;
    }
   
    //wait for all threads
    for(x = 0; x < nthreads; x++)
        if(pthread_join(threadid[x], NULL) < 0)
            perr_quit("pthread join");
   
    //cleanup
    close(lsock);
   
    return 0;
}

u can ignore that setsockopt() stuff with teh sendbuf, musta been someting i was toolin around with.

infamous41md 03-28-2004 05:11 PM

and toss in error checking for read()

Scrag 03-28-2004 07:30 PM

THANKS!!

karlan 03-28-2004 08:12 PM

a good book I purchased was "Linux Socket Programming: By Example"

Scrag 03-28-2004 08:20 PM

infamous41md......could u also post the "my_sock.h" please. THX!

infamous41md 03-28-2004 09:05 PM

Code:

#include        <arpa/inet.h>  /* inet(3) functions */
#include        <asm/errno.h>
#include    <asm/ioctl.h>
#include        <errno.h>
#include        <fcntl.h>              /* for nonblocking */
#include        <in_cksum.h>     
#include    <linux/if.h>
#include    <linux/filter.h>    //for socket filters
#include    <linux/socket.h>
#include    <linux/sockios.h>
#include    <net/ethernet.h>      //ether_addr header
#include        <netinet/in_systm.h>
#include        <netinet/ip.h>
#include        <netinet/ip_icmp.h>
#include        <netinet/tcp.h>
#include        <netinet/udp.h>
#include        <netinet/in.h>  /* sockaddr_in{} and other Internet defns */
#include        <netdb.h>
#include        <sys/types.h>  /* basic system data types */
#include        <sys/socket.h>  /* basic socket definitions */
#include        <sys/time.h>    /* timeval{} for select() */
#include        <sys/stat.h>    /* for S_xxx file mode constants */
#include        <sys/uio.h>            /* for iovec{} and readv/writev */
#include        <sys/wait.h>
#include        <sys/un.h>
#include        <signal.h>
#include        <stdio.h>
#include        <stdlib.h>
#include        <string.h>
#include        <unistd.h>

#if __GLIBC__ >= 2 && __GLIBC_MINOR >= 1
      #include <netpacket/packet.h>
      #include <net/ethernet.h>    /* the L2 protocols */
      #else
      #include <asm/types.h>
      #include <linux/if_packet.h>
      #include <linux/if_ether.h>  /* The L2 protocols */
#endif

//  tcp flags      need to use BSD style tcp header for these #define __FAVOR_BSD to enable it b4 linking 2 library
#define    TCP_FIN    0x01
#define    TCP_SYN    0x02
#define    TCP_RST    0x04
#define    TCP_PUSH    0x08
#define    TCP_ACK    0x10
#define    TCP_URG    0x20

//  internet headers
#define        IP_HDRLEN      20              //duhhh
#define        ICMP_HDRLEN    8
#define        TCP_HDRLEN      20
#define    UDP_HDRLEN  8
#define    ETH_HDRLEN  14

//  useful defines
#define    ETH_BUFSIZE 1500        //max size of ethernet frame w/o header
#define        ADDR_LEN        16              //max len of ascii ip address + NULL terminator

//  LSF OFFSETS these are also useful for otther stuff  as they contain the exact byte offsets off
//          almost all of the header fields. useful to get a value quickly
#define    LSF_IP_V    0x0 //for consistency  ../ mask 0xf0  }  to get these 4 bit values we use
#define    LSF_IP_HL  0x0 //..            ../ mask 0x0f  }  these masks with bitwise &
#define    LSF_IP_TOS  0x1
#define    LSF_IP_TL  0x2
#define    LSF_IP_ID  0x4
#define    LSF_IP_FL  0x6
#define    LSF_IP_TTL  0x8
#define    LSF_IP_P    0x9
#define    LSF_IP_CS  0xa
#define    LSF_IP_SIP  0xc
#define    LSF_IP_DIP  0x10

#define    LSF_UDP_SP  0x0
#define    LSF_UDP_DP  0x2
#define    LSF_UDP_L  0x4
#define    LSF_UDP_CS  0x6

#define    LSF_TCP_SP  0x0
#define    LSF_TCP_DP  0x2
#define    LSF_TCP_SQ  0x4
#define    LSF_TCP_AK  0x8
#define    LSF_TCP_HL  0xc
#define    LSF_TCP_FL  0xd
#define    LSF_TCP_WN  0xe
#define    LSF_TCP_CS  0x10
#define    LSF_TCP_UR  0x12

#define    LSF_E_P    0xc

#define    PS_LEN      0xc
//each of these is bitwise OR'ed to match TCP flags
#define FIN_M          0x01    //...notice the pattern? i hope so! since each flag represents a single bit
#define SYN_M          0x02    //we test for the exact number that indicates that power of 2
#define RST_M          0x04
#define PSH_M          0x08
#define ACK_M          0x10
#define URG_M          0x20

//useful port numbers in hex
#define TLNT            0x17            //23            port numbers in hex
#define FTP            0x15            //21
#define SMTP            0x19            //25
#define POP            0x6e            //110
#define TFTP            0x45            //69
#define HTTP        0x50        //80

#define LEN(x) (sizeof(x)/sizeof(struct sock_filter))  //macro for getting code length

//  useful structures      //need to rename pseudohdr to tcp_ps b/c we have a udp one as well to make
struct pseudohdr        //tcp pseudo header used in calculating checksum

    struct in_addr saddr;  //ip source address    04 bytes
        struct in_addr daddr;  //ip destination address    04 bytes
    u_char pad;    //padding          01 bytes
    u_char protocol;    //protocol          01 bytes
    u_short length;    //tcp total length      02 bytes    --->> sum of this 12 bytes
    struct tcphdr tcpheader;    //tcpheader    20 bytes
};

//ripped right from da kernel
/*
 *  *      Display an IP address in readable format.
 *  */

#define NIPQUAD(addr) \
        ((unsigned char *)&addr)[0], \
        ((unsigned char *)&addr)[1], \
        ((unsigned char *)&addr)[2], \
        ((unsigned char *)&addr)[3]

#define HIPQUAD(addr) \
        ((unsigned char *)&addr)[3], \
        ((unsigned char *)&addr)[2], \
        ((unsigned char *)&addr)[1], \
        ((unsigned char *)&addr)[0]


Scrag 03-28-2004 09:46 PM

Danke

infamous41md 03-28-2004 10:54 PM

have fun, and u should pick up the book mentioned above if u're serious bout network proggin


All times are GMT -5. The time now is 01:49 PM.