LinuxQuestions.org
Share your knowledge at the LQ Wiki.
Home Forums Tutorials Articles Register
Go Back   LinuxQuestions.org > Forums > Non-*NIX Forums > Programming
User Name
Password
Programming This forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game.

Notices


Reply
  Search this Thread
Old 03-28-2004, 03:24 PM   #1
Scrag
Member
 
Registered: Mar 2004
Location: Wisconsin
Distribution: Kali Linux
Posts: 131

Rep: Reputation: 15
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!

 
Old 03-28-2004, 04:01 PM   #2
Chris_tt
LQ Newbie
 
Registered: Mar 2004
Location: Finland
Posts: 5

Rep: Reputation: 0
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
 
Old 03-28-2004, 04:11 PM   #3
infamous41md
Member
 
Registered: Mar 2003
Posts: 804

Rep: Reputation: 30
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.
 
Old 03-28-2004, 04:11 PM   #4
infamous41md
Member
 
Registered: Mar 2003
Posts: 804

Rep: Reputation: 30
and toss in error checking for read()
 
Old 03-28-2004, 06:30 PM   #5
Scrag
Member
 
Registered: Mar 2004
Location: Wisconsin
Distribution: Kali Linux
Posts: 131

Original Poster
Rep: Reputation: 15
THANKS!!
 
Old 03-28-2004, 07:12 PM   #6
karlan
Member
 
Registered: Aug 2003
Location: San Francisco, California
Distribution: Slackware
Posts: 158

Rep: Reputation: 30
a good book I purchased was "Linux Socket Programming: By Example"
 
Old 03-28-2004, 07:20 PM   #7
Scrag
Member
 
Registered: Mar 2004
Location: Wisconsin
Distribution: Kali Linux
Posts: 131

Original Poster
Rep: Reputation: 15
infamous41md......could u also post the "my_sock.h" please. THX!
 
Old 03-28-2004, 08:05 PM   #8
infamous41md
Member
 
Registered: Mar 2003
Posts: 804

Rep: Reputation: 30
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]
 
Old 03-28-2004, 08:46 PM   #9
Scrag
Member
 
Registered: Mar 2004
Location: Wisconsin
Distribution: Kali Linux
Posts: 131

Original Poster
Rep: Reputation: 15
Danke
 
Old 03-28-2004, 09:54 PM   #10
infamous41md
Member
 
Registered: Mar 2003
Posts: 804

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


Reply



Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is Off
HTML code is Off



Similar Threads
Thread Thread Starter Forum Replies Last Post
Unable to connect to UNIX socket /tmp/.esd/socket error while using grip dr_zayus69 Linux - Software 4 08-23-2005 07:28 PM
UNIX (Linux, BSD, etc) Programming :: UNIX kuphryn Programming 8 04-04-2004 11:50 PM
How to set SQL to UNIX socket Skunk_Face Linux - General 1 01-19-2004 06:20 AM
newbie: unix network programming: UDP and send file geo_h Programming 3 09-17-2003 11:41 AM
KDevelop Unix Socket Problem shibdas Linux - Software 0 07-30-2003 01:50 PM

LinuxQuestions.org > Forums > Non-*NIX Forums > Programming

All times are GMT -5. The time now is 12:29 AM.

Main Menu
Advertisement
My LQ
Write for LQ
LinuxQuestions.org is looking for people interested in writing Editorials, Articles, Reviews, and more. If you'd like to contribute content, let us know.
Main Menu
Syndicate
RSS1  Latest Threads
RSS1  LQ News
Twitter: @linuxquestions
Open Source Consulting | Domain Registration