網絡編程,一個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;
}




發佈了46 篇原創文章 · 獲贊 4 · 訪問量 9萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章