RE: TCP/IP - Sockets appear to be restricted to maximum 65,535 byte transfers
From: Dan Allen (dallen_at_nist.gov)
Date: 03/07/05
- Next message: John Reagan: "Re: new Itanium after Tukwila: Poulson"
- Previous message: John Reagan: "Re: new Itanium after Tukwila: Poulson"
- Maybe in reply to: Roy Omond: "TCP/IP - Sockets appear to be restricted to maximum 65,535 byte transfers"
- Next in thread: Roy Omond: "Re: TCP/IP - Sockets appear to be restricted to maximum 65,535 byte transfers"
- Reply: Roy Omond: "Re: TCP/IP - Sockets appear to be restricted to maximum 65,535 byte transfers"
- Messages sorted by: [ date ] [ thread ] [ subject ] [ author ]
Date: Mon, 7 Mar 2005 11:20:39 -0500
Well - documentation aside - TCP sockets are byte streams. The size of the
actual TCP packets are not necessarily related to the application read/write
sizes. Just read and write in chunk sizes of your choosing. The TCP layer will
packetize it at whim anyway.
HTH,
Dan
> -----Original Message-----
> From: Roy Omond [mailto:Roy.Omond@BlueBubble.UK.Com]
> Sent: Monday, March 07, 2005 10:52 AM
> To: Info-VAX@Mvb.Saic.Com
> Subject: TCP/IP - Sockets appear to be restricted to maximum 65,535 byte
> transfers
>
>
> Gentle colleagues,
>
> this is becoming a bit of a showstopper for me:
>
> A very simple pair of programs (Server and Client) are setup
> to transfer a quantity of data via a TCP Socket. The background
> to this is actually in trying to get this to work in UCX v3.3 ECO 3,
> whereas it worked flawlessly (and as per the documentation) in
> vanilla UCX v3.3 (without ECO), running under VAX VMS 6.2.
>
> The problem is easily demonstrated on VMS 7.3-2 (Alpha) with
> TCP/IP Services v5.4 ECO 4, as well as all the versions after
> UCX v3.3 ECO 3 and above (both VAX and Alpha).
>
> The Server process establishes a socket, listens for an accept on the
> socket (which the Client sends), and sends an amount of data down the
> socket to the client. That's it. It works fine with data up to and
> including 65,535 bytes. Beyond this, it returns an error
> ("%system-f-ivbuflen, invalid buffer length").
> I can find no mention in the documentation "TCP/IP Sockets API
> and System Services Programming" of any such restriction on the
> amount of data to transfer.
>
> Here are the 2 small programs:
>
> --- cut here ---
>
> $ create client.c
> #include <errno.h>
> #include <stdio.h>
> #include <sys/types.h>
> #include <sys/socket.h>
> #include <netinet/in.h>
> #include "sys/ioctl.h"
> #include <netdb.h>
> /*
> struct hostent
> *VGetHostByName(char *name)
> {
> struct hostent *h;
> int i;
>
> if (name == NULL)
> {
> return(NULL);
> }
> sethostent( 1 );
>
> while ((h = gethostent()) != NULL)
> {
> if (strcmp(name,h->h_name) == 0) {
> endhostent();
> return(h);
> }
> i = 0;
> while (h->h_aliases[i] != NULL) {
> if (strcmp(name,h->h_aliases[i]) == 0) {
> endhostent();
> return(h);
> }
> i++;
> }
> }
> endhostent();
> return( NULL );
> }*/
>
> main (int argc, char ** argv)
> {
> int sock;
> int byte_count;
> int bcount;
> char data[1000000];
> int sendbuf;
> int len;
>
> static struct hostent *mh,master_host;
> static struct sockaddr_in sin;
>
> if ((sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)) == -1)
> {
> perror ("Create Socket:");
> printf ("errno in CreateSock is %d\n", errno);
> return(-1);
> }
>
> if (argc > 1)
> {
> printf ("Connecting to host %s\n", argv[1]);
> mh = GetHostByName(argv[1]);
> if (mh == NULL)
> {
> perror ("GetHostByName:");
> printf ("Can't get host name %s\n", argv[1]);
> close(sock);
> return (-1);
> }
> }
> else
> {
> printf ("Need a host name\n");
> return (-1);
> }
>
> master_host = *mh;
>
> sin.sin_family = master_host.h_addrtype;
> sin.sin_port = 50000;
> memcpy(&sin.sin_addr, master_host.h_addr, master_host.h_length);
>
> if (connect(sock, &sin, sizeof(struct sockaddr_in)) == -1)
> {
> perror ("Connect:");
> return (-1);
> }
>
> len = sizeof(sendbuf);
> if (getsockopt(sock,SOL_SOCKET,SO_SNDBUF,&sendbuf,&len) < 0)
> {
> perror("getsockopt SO_SNDBUF");
> }
> printf("Send buffer %d bytes\n",sendbuf);
>
> while (1)
> {
> ioctl(sock, FIONREAD, &bcount);
>
> if (bcount > 0)
> {
> int cnt = 0;
> if ((bcount = read (sock, (char *)&byte_count,sizeof(int))) == -1)
> {
> perror ("Read data size");
> return (-1);
> }
> printf ("Read %d bytes, count is %d\n", bcount, byte_count);
>
> bcount = 0;
> while (cnt < byte_count)
> {
> if ((bcount = read (sock, data, byte_count - cnt)) == -1)
> {
> perror ("Read data");
> return (-1);
> }
> printf ("Read %d\n", bcount);
> cnt += bcount;
> }
> printf ("Read %d bytes total\n", cnt);
> break;
> }
> }
> }
>
> $ create server.c
> #include <errno.h>
> #include <stdio.h>
> #include <sys/types.h>
> #include <sys/socket.h>
> #include <netinet/in.h>
> #include <ucx$inetdef.h>
>
> int
> writevv (int fd, struct iovec * iov, int iovcnt)
> {
> int total_bytes = 0, bytes, i;
>
> for (i = 0; i < iovcnt; i++)
> {
> bytes = write (fd, iov[i].iov_base, iov[i].iov_len);
> if (bytes == -1)
> {
> perror ("write:");
> return (-1);
> }
> else
> {
> total_bytes += bytes;
> }
> }
> return (total_bytes);
> }
>
> main (int argc, char ** argv)
> {
>
> int serv_sock = -1;
> int client_sock = -1;
> int len;
>
> int data_size = 1000;
>
> if (argc >= 2) data_size = atoi(argv[1]);
>
> if ((serv_sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)) == -1)
> {
> perror ("Create Socket:");
> printf ("errno in CreateSock is %d\n", errno);
> return(-1);
> }
>
> len=sizeof(data_size);
>
> if (setsockopt(serv_sock,SOL_SOCKET,SO_SNDBUF,&data_size,len) < 0)
> {
> perror("setsockopt SO_SNDBUF");
> }
>
> if (setsockopt(serv_sock,SOL_SOCKET,SO_RCVBUF,&data_size,len) < 0)
> {
> perror("setsockopt SO_RCVBUF");
> }
> printf("Send/Receive buffer %d bytes\n",data_size);
>
> {
> static struct sockaddr_in sin;
> sin.sin_family = htons(AF_INET);
> sin.sin_port = 50000;
> sin.sin_addr.s_addr = htonl(INADDR_ANY);
>
> if (bind(serv_sock, &sin, sizeof(sin)) == -1)
> {
> printf("cannot bind socket to port");
> perror ("Bind:");
> return(-1);
> }
> }
>
> if (listen(serv_sock, 20) == -1)
> {
> printf("cannot set listen(s,20)");
> perror ("Listen:");
> return(-1);
> }
>
> if ((client_sock = accept(serv_sock, NULL, NULL)) > 0)
> {
> struct iovec iov[2];
> int count;
> static char data[1000000];
>
> if (data_size > 1000000) data_size = 1000000;
> iov[0].iov_base = (char *) &data_size;
> iov[0].iov_len = sizeof(int);
> iov[1].iov_base = &data;
> iov[1].iov_len = data_size;
>
> if (writevv(client_sock,iov,2) == -1)
> {
> perror ("writev:");
> return (-1);
> }
> sleep(10);
> }
> }
> $ server:=$u:[xxxx]server
> $ client:=$u:[xxxx]client
> $ spawn/nowait server 65536
> $ client my-node-name
>
>
>
> Any comments ? Any suggestions ? I thinks this, at worst, a
> bug in the Socket implementation, or, at "best", a serious
> omission in the documentation.
>
> Note, as mentioned above, this worked fine in UCX v3.3, but
> not in UCX v3.3 ECO 3 or later.
>
> Many thanks in advance,
>
> Roy Omond
> Blue Bubble Ltd.
>
>
- Next message: John Reagan: "Re: new Itanium after Tukwila: Poulson"
- Previous message: John Reagan: "Re: new Itanium after Tukwila: Poulson"
- Maybe in reply to: Roy Omond: "TCP/IP - Sockets appear to be restricted to maximum 65,535 byte transfers"
- Next in thread: Roy Omond: "Re: TCP/IP - Sockets appear to be restricted to maximum 65,535 byte transfers"
- Reply: Roy Omond: "Re: TCP/IP - Sockets appear to be restricted to maximum 65,535 byte transfers"
- Messages sorted by: [ date ] [ thread ] [ subject ] [ author ]
Relevant Pages
|