网络编程基础

  • 进程的网络地址:

    进程是出于运行过程中的程序实例,是操作系统调度和分配的基本单位。每个进程至少拥有一个线程否则,系统会自动撤销该进程和它的地址空间。

  • 三种套接字:

    • 数据报套接字:无连接,不保证可靠,独立的数据传输服务。
    • 流式套接字:提供双向、有序、无重复、无边界记录、可靠的数据传输服务。需要事先建立连接。
    > 面向连接的协议和面向无连接的区别在明白了这个之后变得很清楚。
    
    • 原始套接字:允许直接访问较低层的协议(如IP,ICMP)用与检验新的协议的实现。
  • 网络协议的特征:

  1. 面向消息的协议与基于流的协议:
    • 面向消息的协议:以消息为单位在网上传输数据。一条一条的发送与接收。每条消息间都是独立的,存在着消息边界。
    • 基于流的协议: 不保护消息的边界,将数据拆封成字节流连续的传输,不管实际消息边界是否存在,TCP就是基于流的协议。
  2. 面向连接和无连接的服务:
    • 面向连接:每一次完整的传输数据都要建立连接。在数据传输中,各数据分组不携带目的地址,而是使用连接号。本质上讲,连接是一个管道。通信前通过握手,相互传送连接信息,一方面确定了通行的路径,另一方面还可以相互协商,做好通信的准备,例如:准备收发的缓冲区。
    • 面向无连接:类似邮政系统服务的抽象。每个分组都携带完整的目的地址,各分组在系统中独立传送。无法保证分组先后到达的顺序,不进行分组的恢复与重传,不保证传输的可靠性。UDP就是无连接的协议。
    • 可靠性和次序性:
      可靠性:可靠性保证了发送端发送的每一个字节都达到既定的接受端,保证数据的完整性。
      次序性:保证收到的数据的顺序就是发送端发送的顺序。
  • P2P(对等网、点对点)

    • P2P技术:在计算机直接直接进行资源和服务共享。
    • 特征:
      1. 分散性:分布式系统
      2. 规模性:
      3. 扩展性:随时加入
      4. Servent性(sever&client)
      5. 自治性:自行加入与退出
      6. 互助性
      7. 自组织性:自行组织不需要任何管理员
  • Internet中网间进程的标识

    • 用一个三元组可以在全局中唯一的标识一个应用层进程:
      1. 传输层协议
      2. 主机的IP地址
      3. 传输层的端口号

Winsock下文件传输:

文件传输
1, 注册套接字函数socket(int af,int type,int protocol)
参数解释:
af : 一个地址描述 ,目前只支持AF_INET格式,也就是说在本次实验中此参数直接写
为AF_INET即可。
type: 指定socket类型,例如 TCP类型(SOCK_STREAM) UDP类型(SOCK_DGRAM)

protocol: 套接口制订协议类型 可以为0,。 常用类型有 IPPROTO_TCP 、IPPROTO_UDP等

2, 绑定套接字函数 bind ( SOCKET s , const struct sockaddr FAR *addr , int namelen );
参数解释:
s :socket()函数返回的套接口描述字
addr : 指向Socket地址的指针
namelen :该地址的长度

3,监听函数listen(SOCKET s,int backlog)
参数解释:
s: socket()函数返回的套接口描述字

backlog:等待连接队列的最大长度

4,接收连接函数accept(SOCKET s,struct sockaddr FAR* addr,int FAR* addrlen)
参数解释:
s: socket()函数返回的套接口描述字

addr:(可选)指针,指向一缓冲区,其中接收为通讯层所知的连接实体的地址。addr参数的实际格式由套接口创建时所产生的地址族确定

addrlen:(可选)指针,输入参数,配合addr一起使用,指向存有addr地址长度的整型数

5, 发送连接请求函数connect(SOCKET s,const struct coskaddr FAR* name,int namelen)
参数解释:
s: socket()函数返回的套接口描述字

name: 想要进行连接的端口名

namelen: 名字长度

6,发送数据函数send( SOCKET s, const char FAR* buf, int len, int flags)
接收文件函数recv(SOCKET s, char FAR* buf, int len, int flags)
参数解释:
s:socket()函数返回的套接口描述字
buf:用于接收数据的缓冲区
len:缓冲区长度
flags:指定调用方式
7,文件操作函数fopen(const char * path,const char * mode) fclose(FILE* stream)
参数解释:

path:欲打开的文件路径及文件名

mode:代表流形态

stream:文件流指针

客户端
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <WinSock2.h>
#include <ws2tcpip.h>
#pragma comment(lib,"ws2_32.lib")

  #define MAXLINE 1024
  #define SEVERPORT 1026
  #define SEVERPORTADDR "192.168.1.110"

  int main () 
  {
WSADATA wsaData;//wsdate 用于存储调用windock中socket初始化函数返回的初始化信息 
WORD socketVersion = MAKEWORD(2.2); //就是一个word地位用来指明主版本号,高位用来指明修正号
//初始化windows socket
if (0 != WSAStratup(socketVersion,&wsaData)) {
    printf("初始化失败!\n");
    exit(0);
}
char recvbuff[MAXLINE + 1]; //创建缓冲区
int sockfd,n;//socket标志字,那么fd是什么意思呢,fd是file descriptor的缩写。顾名思义就是文件描述符啦。
//设置地址
struct sockaddr_in servaddr;
//给地址初始化
memset(&servaddr,0,sizeof(servaddr));
//设置使用IPV4通信
servaddr.sin_family = AF_INET;
servaddr.sin_port = htons(SEVERPORT);//host to network short int;
//sin_addr中的联合S_un包含的s_un.s_addr 意思为An IPv4 address formatted as a u_long
servaddr.sin_addr.S_un.S_addr = inet_addr(SEVERPORTADDR);
//生成套接字
if ((sockfd  = socket(AF_INET,SOCK_STREAM.0)) < 0) {
    printf("sockfd error!\n");
    exit(0);
}

//尝试连接服务器
printf("请输入要传输的文件\n");

char filename[256];
scanf("%s",filename);

//建立文件缓冲区,定义文件指针,指向传输文件
FILE * fp = (FILE *)NULL;//初始化文件指针

fp = fopen(filename,"rb"); //用二进制格式打开一个文件,只允许读。


if (fp == (FILE *)NULL) {
    printf("打开文件失败!\n");
    return 0;
}

//发送文件名
n = send(sockfd, filename, strlen(filename), 0);
//如果无错误,返回值为发送数据的总数
printf("发送数据为:%d\n",n);

//接受服务器返回的信息
 n = recv(sockfd,recvbuff,MAXLINE,0);
 
if(strcmp(recvbuff,  "ok") == 0){//如果服务器返回ok则开始传送文件
    memset(recvbuff, 0, sizeof(recvbuff));
    while(!feof(fp)){
        n = fread(recvbuff, sizeof(char), 1000, fp);
        printf("%d\n", n);
        n = send(sockfd, recvbuff, n, 0);
        printf("send n = %d\n", n);
    }//传送文件
    fclose(fp);//关闭文件
}
closesocket(sockfd);
//关闭网络描述符
return 0;
  }

服务器
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<WinSock2.h>

  #define PORTNUMBER 3333 //定义端口号
  #define MAXLINE           1024 //缓存大小
  #pragma comment(lib,"ws2_32.lib")

  #define QueueLen 1

  char buffer[MAXLINE+1];
  int n;
  int  main(int argc, char * argv[])
  {
WORD version;
version = MAKEWORD(1, 1);
WSADATA wsa;
if(0 != WSAStartup(version, &wsa)){ 
            printf("WSAStartup error!\n");
          exit(0);
      }//初始化 socket

struct sockaddr_in servaddr; //服务器IP地址
struct sockaddr_in clientaddr;//客户端IP地址
int listenfd;//监听的网络描述符
int clientfd;//客户端网络描述符
int alen;

memset(&servaddr, 0, sizeof(servaddr)); //初始化

servaddr.sin_family = AF_INET;
servaddr.sin_addr.s_addr = INADDR_ANY; //INADDR_ANY 你网卡上的任意IP,比如你有多个IP
servaddr.sin_port = htons((unsigned short) PORTNUMBER); 
//初始化服务器

listenfd =  socket(AF_INET, SOCK_STREAM, IPPROTO_IP ); 
//初始化监听的网络描述符
if(listenfd< 0){
    fprintf(stderr, "socket createion failed!\n");
    exit(0);
}//失败
if(bind(listenfd, (struct  sockaddr *) &servaddr, sizeof(servaddr)) < 0){
    fprintf(stderr, "bind failed!\n");
    exit(0);
}//版定到端口
if(listen(listenfd, QueueLen) < 0){
    fprintf(stderr, "listen failed!\n");
    exit(0);
}//绑定失败
char filename[256];
while(1){
    alen = sizeof(clientaddr);
    if((clientfd = accept(listenfd, (struct sockaddr*)&clientaddr, &alen)) < 0){
        fprintf(stderr, "accept failed!\n");
        exit(0);
    }//接受客户端的连接
    n = recv(clientfd, filename, 255, 0);//接受客户端发送的信息
    filename[n] = '\0';
    printf("recv n = %d\n", n);
    FILE * fp = (FILE *)NULL;
    if((FILE *) NULL == (fp = fopen(filename, "wb"))){
        printf("open file %s failed!\n", filename);
        return 0;
    }
    n = send(clientfd, "ok", strlen("ok"), 0);
    //发送 ok 到客户端,让客户端开始发送文件
    printf("send n = %d\n", n);
    while(n = recv(clientfd, buffer, 1000, 0)){
        printf("recv n = %d\n", n);
        fwrite(buffer, sizeof(char), n, fp);
        if(n != 1000)
            break;
    }//接受文件并保存
    fclose(fp);
    closesocket(clientfd);
    //关闭文件,关闭网络描述符
}
return 0;
 }
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 215,463评论 6 497
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,868评论 3 391
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 161,213评论 0 351
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,666评论 1 290
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,759评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,725评论 1 294
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,716评论 3 415
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,484评论 0 270
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,928评论 1 307
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,233评论 2 331
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,393评论 1 345
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,073评论 5 340
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,718评论 3 324
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,308评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,538评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,338评论 2 368
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,260评论 2 352

推荐阅读更多精彩内容

  • 1.1 网络常识 1)网络的7层网络协议 ISO按照逻辑划分出来7层网络协议 应用层:和应用程序打交道的,进行数据...
    vera姐姐阅读 476评论 0 1
  • 网络编程基础1 URL url(统一资源定位符 Uniform Resourse Locator)通过一个URl,...
    董军1990阅读 7,399评论 8 45
  • #Socket简介 是一个编程接口 是一种特殊的文件描述符(everything in Unix is a fil...
    我替上帝收尸阅读 1,991评论 0 1
  • 一、Socket简介Socket是进程通讯的一种方式,即调用这个网络库的一些API函数实现分布在不同主机的相关进程...
    小吖朱阅读 331评论 0 1
  • 众得处分,退而递相谓曰:我等众人,不须澄心用意作偈,将呈和尚有何所益?神秀上座现为教授师,必是他得。我辈谩作...
    回归当初阅读 1,083评论 0 0