网络编程,一个ACSII文件的传输

为了简单,这个程序没有套接字的错误处理逻辑。原文件名跟传输后存储的文件名都是程序里写死的。

如果想得到更安全的网络编程例子,推荐 《网络编程 卷1》,这本书真的讲得很好,很详细。

简单的网络编程无非就是那几步。

创建服务端

1.创建套接字

int s = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP);

2.绑定地址

阐述下in_addr的含义,很显然它是一个存储ip地址的联合体有三种表达方式:
第一种用四个字节来表示IP地址的四个数字;
第二种用两个双字节来表示IP地址;
第三种用一个长整型来表示IP地址。
struct sockaddr_in channel;
	memset(&channel, 0, sizeof(channel));
	channel.sin_family = AF_INET;
	channel.sin_port = htons(SERVER_PORT);
	channel.sin_addr.s_addr = htonl(INADDR_ANY);
INADDR_ANY 表示任何地址都可以连接这个套接字 ,网络字节序是big endian。

3.监听

listen(s,5);

SYNOPSIS
       #include <sys/types.h>          /* See NOTES */
       #include <sys/socket.h>

       int listen(int sockfd, int backlog);

DESCRIPTION
       listen()  marks  the  socket referred to by sockfd as a passive socket,
       that is, as a socket that will be used to  accept  incoming  connection
       requests using accept(2).

       The  sockfd  argument  is  a file descriptor that refers to a socket of
       type SOCK_STREAM or SOCK_SEQPACKET.

       The backlog argument defines the maximum length to which the  queue  of
       pending  connections  for  sockfd  may  grow.   If a connection request
       arrives when the queue is full, the client may receive an error with an
       indication  of  ECONNREFUSED  or,  if  the underlying protocol supports
       retransmission, the request may be ignored so that a later reattempt at
       connection succeeds.

4.接受连接

int acc = accept(s, 0,0);

SYNOPSIS
       #include <sys/types.h>          /* See NOTES */
       #include <sys/socket.h>


       int accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen);

addr,与addrlen 是返回客户端连接的套接字绑定的地址,如果我们不需要连接的客户端地址的话,可以将此两值赋为NULL。

5.传输数据

read(), write().


创建客户端

1.创建套接字

同创建服务端

2.创建连接

struct sockaddr_in channel;
	memset(&channel, 0, sizeof(channel));
	channel.sin_family = AF_INET;
	channel.sin_port = htons(SERVER_PORT);
	channel.sin_addr.s_addr =  inet_addr("127.0.0.1");

	connect(s, (struct sockaddr* )&channel, sizeof(channel));

 SYNOPSIS
       #include <sys/socket.h>
       #include <netinet/in.h>
       #include <arpa/inet.h>

       in_addr_t inet_addr(const char *cp);

The inet_addr() function converts the Internet host address cp from IPv4 numbers-and-dots notation into binary data  in  network  byte
       order.
  If  the  input  is  invalid, INADDR_NONE (usually -1) is returned.  Use of this function is problematic because -1 is a valid
       address (255.255.255.255).  Avoid its use in favor of inet_aton(), inet_pton(3), or getaddrinfo(3) which  provide  a  cleaner  way  to
       indicate error return.

127.0.0.1是回送地址,指本地机,一般用来测试使用。

SYNOPSIS
       #include <sys/types.h>          /* See NOTES */
       #include <sys/socket.h>


       int connect(int sockfd, const struct sockaddr *addr, socklen_t addrlen);

3.传输数据

同创建服务端

服务器源代码

#include <iostream>
#include <sys/types.h>     //socket()  , bind, accept, listen
#include <sys/socket.h>   //socket()  , bind, accept, listen
#include <netinet/in.h>
#include <unistd.h>            //read(), write()
//#include <cstdlib>
#include <cstring>             // memset
//#include <cstdio>
 //#include <sys/stat.h>
#include <fcntl.h>               // open

#define SERVER_PORT 12345
#define BUF_SIZE 4096

using namespace std;

int main(int argc, char ** argv)
{


	int s = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP);
	if(s < 0)
		cerr<<"socket failed"<<endl;

	struct sockaddr_in channel;
	memset(&channel, 0, sizeof(channel));
	channel.sin_family = AF_INET;
	channel.sin_port = htons(SERVER_PORT);
	channel.sin_addr.s_addr = htonl(INADDR_ANY);

	bind(s, (struct sockaddr*)&channel , sizeof(channel));
	listen(s,5);

    char buf[BUF_SIZE];
    int acc = accept(s, 0,0);
    char buf1[] = "test.txt";

     int fd = open(buf1,O_CREAT | O_RDWR);
    if(fd <0 )
        return -1;

     int byte = 0;
     while( (byte = read(acc,buf,10) ) > 0 )
     {
        write(fd,buf,byte);
        cout<<"receive something: "<<buf<<endl;
     }

    close(fd);
	return 0;
}

客户端代码

#include <iostream>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <unistd.h>
//#include <netdb.h>
#include <cstdlib>
#include <cstring>
#include <cstdio>
 #include <sys/stat.h>
#include <fcntl.h>

#define SERVER_PORT 12345
#define BUF_SIZE 4096

using namespace std;

int main(int argc, char ** argv)
{


	int s = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP);
	if(s < 0)
		cerr<<"socket failed"<<endl;

	struct sockaddr_in channel;
	memset(&channel, 0, sizeof(channel));
	channel.sin_family = AF_INET;
	channel.sin_port = htons(SERVER_PORT);
	channel.sin_addr.s_addr =  inet_addr("127.0.0.1");

	connect(s, (struct sockaddr* )&channel, sizeof(channel));
    char buf[BUF_SIZE] ;

  //  if(argc <= 1)
  //      return -1;

    char buf1[] = "test.txt";
    int fd = open(buf1, O_RDONLY);
    //int fd = open(argv[1],O_RDONLY);
    if(fd <0)
        return -1;
        
    int byte = 0;
    while( (byte = read(fd,buf,BUF_SIZE) ) > 0)
    {
       cout<<"send something: "<<buf<<endl;
        write(s,buf,strlen(buf) + 1);
    }

    close(fd);
	return 0;
}




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值