-
進(jìn)程的網(wǎng)絡(luò)地址:
進(jìn)程是出于運(yùn)行過(guò)程中的程序?qū)嵗遣僮飨到y(tǒng)調(diào)度和分配的基本單位兔仰。每個(gè)進(jìn)程至少擁有一個(gè)線程否則,系統(tǒng)會(huì)自動(dòng)撤銷該進(jìn)程和它的地址空間乎赴。
-
三種套接字:
- 數(shù)據(jù)報(bào)套接字:無(wú)連接,不保證可靠榕吼,獨(dú)立的數(shù)據(jù)傳輸服務(wù)。
- 流式套接字:提供雙向羹蚣、有序、無(wú)重復(fù)顽素、無(wú)邊界記錄、可靠的數(shù)據(jù)傳輸服務(wù)胁出。需要事先建立連接。
> 面向連接的協(xié)議和面向無(wú)連接的區(qū)別在明白了這個(gè)之后變得很清楚全蝶。
- 原始套接字:允許直接訪問(wèn)較低層的協(xié)議(如IP寺枉,ICMP)用與檢驗(yàn)新的協(xié)議的實(shí)現(xiàn)绷落。
-
網(wǎng)絡(luò)協(xié)議的特征:
- 面向消息的協(xié)議與基于流的協(xié)議:
- 面向消息的協(xié)議:以消息為單位在網(wǎng)上傳輸數(shù)據(jù)姥闪。一條一條的發(fā)送與接收砌烁。每條消息間都是獨(dú)立的,存在著消息邊界往弓。
- 基于流的協(xié)議: 不保護(hù)消息的邊界,將數(shù)據(jù)拆封成字節(jié)流連續(xù)的傳輸函似,不管實(shí)際消息邊界是否存在,TCP就是基于流的協(xié)議撇寞。
- 面向連接和無(wú)連接的服務(wù):
- 面向連接:每一次完整的傳輸數(shù)據(jù)都要建立連接顿天。在數(shù)據(jù)傳輸中蔑担,各數(shù)據(jù)分組不攜帶目的地址牌废,而是使用連接號(hào)啤握。本質(zhì)上講鸟缕,連接是一個(gè)管道排抬。通信前通過(guò)握手,相互傳送連接信息蹲蒲,一方面確定了通行的路徑,另一方面還可以相互協(xié)商届搁,做好通信的準(zhǔn)備,例如:準(zhǔn)備收發(fā)的緩沖區(qū)卡睦。
- 面向無(wú)連接:類似郵政系統(tǒng)服務(wù)的抽象。每個(gè)分組都攜帶完整的目的地址么翰,各分組在系統(tǒng)中獨(dú)立傳送。無(wú)法保證分組先后到達(dá)的順序浩嫌,不進(jìn)行分組的恢復(fù)與重傳,不保證傳輸?shù)目煽啃月肽汀DP就是無(wú)連接的協(xié)議。
- 可靠性和次序性:
可靠性:可靠性保證了發(fā)送端發(fā)送的每一個(gè)字節(jié)都達(dá)到既定的接受端骚腥,保證數(shù)據(jù)的完整性。
次序性:保證收到的數(shù)據(jù)的順序就是發(fā)送端發(fā)送的順序束铭。
-
P2P(對(duì)等網(wǎng)、點(diǎn)對(duì)點(diǎn))
- P2P技術(shù):在計(jì)算機(jī)直接直接進(jìn)行資源和服務(wù)共享契沫。
- 特征:
- 分散性:分布式系統(tǒng)
- 規(guī)模性:
- 擴(kuò)展性:隨時(shí)加入
- Servent性(sever&client)
- 自治性:自行加入與退出
- 互助性
- 自組織性:自行組織不需要任何管理員
-
Internet中網(wǎng)間進(jìn)程的標(biāo)識(shí)
- 用一個(gè)三元組可以在全局中唯一的標(biāo)識(shí)一個(gè)應(yīng)用層進(jìn)程:
- 傳輸層協(xié)議
- 主機(jī)的IP地址
- 傳輸層的端口號(hào)
- 用一個(gè)三元組可以在全局中唯一的標(biāo)識(shí)一個(gè)應(yīng)用層進(jìn)程:
Winsock下文件傳輸:
文件傳輸
1, 注冊(cè)套接字函數(shù)socket(int af,int type,int protocol)
參數(shù)解釋:
af : 一個(gè)地址描述 ,目前只支持AF_INET格式,也就是說(shuō)在本次實(shí)驗(yàn)中此參數(shù)直接寫(xiě)
為AF_INET即可拴清。
type: 指定socket類型,例如 TCP類型(SOCK_STREAM) UDP類型(SOCK_DGRAM)
protocol: 套接口制訂協(xié)議類型 可以為0,口予。 常用類型有 IPPROTO_TCP 、IPPROTO_UDP等
2, 綁定套接字函數(shù) bind ( SOCKET s , const struct sockaddr FAR *addr , int namelen );
參數(shù)解釋:
s :socket()函數(shù)返回的套接口描述字
addr : 指向Socket地址的指針
namelen :該地址的長(zhǎng)度
3沪停,監(jiān)聽(tīng)函數(shù)listen(SOCKET s,int backlog)
參數(shù)解釋:
s: socket()函數(shù)返回的套接口描述字
backlog:等待連接隊(duì)列的最大長(zhǎng)度
4,接收連接函數(shù)accept(SOCKET s,struct sockaddr FAR* addr,int FAR* addrlen)
參數(shù)解釋:
s: socket()函數(shù)返回的套接口描述字
addr:(可選)指針木张,指向一緩沖區(qū)窟哺,其中接收為通訊層所知的連接實(shí)體的地址技肩。addr參數(shù)的實(shí)際格式由套接口創(chuàng)建時(shí)所產(chǎn)生的地址族確定
addrlen:(可選)指針虚婿,輸入?yún)?shù)至朗,配合addr一起使用剧浸,指向存有addr地址長(zhǎng)度的整型數(shù)
5嫌变, 發(fā)送連接請(qǐng)求函數(shù)connect(SOCKET s,const struct coskaddr FAR* name,int namelen)
參數(shù)解釋:
s: socket()函數(shù)返回的套接口描述字
name: 想要進(jìn)行連接的端口名
namelen: 名字長(zhǎng)度
6,發(fā)送數(shù)據(jù)函數(shù)send( SOCKET s, const char FAR* buf, int len, int flags)
接收文件函數(shù)recv(SOCKET s, char FAR* buf, int len, int flags)
參數(shù)解釋:
s:socket()函數(shù)返回的套接口描述字
buf:用于接收數(shù)據(jù)的緩沖區(qū)
len:緩沖區(qū)長(zhǎng)度
flags:指定調(diào)用方式
7,文件操作函數(shù)fopen(const char * path,const char * mode) fclose(FILE* stream)
參數(shù)解釋:
path:欲打開(kāi)的文件路徑及文件名
mode:代表流形態(tài)
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 用于存儲(chǔ)調(diào)用windock中socket初始化函數(shù)返回的初始化信息
WORD socketVersion = MAKEWORD(2.2); //就是一個(gè)word地位用來(lái)指明主版本號(hào)东涡,高位用來(lái)指明修正號(hào)
//初始化windows socket
if (0 != WSAStratup(socketVersion,&wsaData)) {
printf("初始化失敗凸舵!\n");
exit(0);
}
char recvbuff[MAXLINE + 1]; //創(chuàng)建緩沖區(qū)
int sockfd,n;//socket標(biāo)志字,那么fd是什么意思呢贿条,fd是file descriptor的縮寫(xiě)整以。顧名思義就是文件描述符啦峻仇。
//設(shè)置地址
struct sockaddr_in servaddr;
//給地址初始化
memset(&servaddr,0,sizeof(servaddr));
//設(shè)置使用IPV4通信
servaddr.sin_family = AF_INET;
servaddr.sin_port = htons(SEVERPORT);//host to network short int;
//sin_addr中的聯(lián)合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);
}
//嘗試連接服務(wù)器
printf("請(qǐng)輸入要傳輸?shù)奈募n");
char filename[256];
scanf("%s",filename);
//建立文件緩沖區(qū)凡蚜,定義文件指針,指向傳輸文件
FILE * fp = (FILE *)NULL;//初始化文件指針
fp = fopen(filename,"rb"); //用二進(jìn)制格式打開(kāi)一個(gè)文件谱醇,只允許讀副渴。
if (fp == (FILE *)NULL) {
printf("打開(kāi)文件失斨缶纭勉盅!\n");
return 0;
}
//發(fā)送文件名
n = send(sockfd, filename, strlen(filename), 0);
//如果無(wú)錯(cuò)誤漩符,返回值為發(fā)送數(shù)據(jù)的總數(shù)
printf("發(fā)送數(shù)據(jù)為:%d\n",n);
//接受服務(wù)器返回的信息
n = recv(sockfd,recvbuff,MAXLINE,0);
if(strcmp(recvbuff, "ok") == 0){//如果服務(wù)器返回ok則開(kāi)始傳送文件
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);//關(guān)閉文件
}
closesocket(sockfd);
//關(guān)閉網(wǎng)絡(luò)描述符
return 0;
}
服務(wù)器
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<WinSock2.h>
#define PORTNUMBER 3333 //定義端口號(hào)
#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; //服務(wù)器IP地址
struct sockaddr_in clientaddr;//客戶端IP地址
int listenfd;//監(jiān)聽(tīng)的網(wǎng)絡(luò)描述符
int clientfd;//客戶端網(wǎng)絡(luò)描述符
int alen;
memset(&servaddr, 0, sizeof(servaddr)); //初始化
servaddr.sin_family = AF_INET;
servaddr.sin_addr.s_addr = INADDR_ANY; //INADDR_ANY 你網(wǎng)卡上的任意IP凸克,比如你有多個(gè)IP
servaddr.sin_port = htons((unsigned short) PORTNUMBER);
//初始化服務(wù)器
listenfd = socket(AF_INET, SOCK_STREAM, IPPROTO_IP );
//初始化監(jiān)聽(tīng)的網(wǎng)絡(luò)描述符
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);//接受客戶端發(fā)送的信息
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);
//發(fā)送 ok 到客戶端,讓客戶端開(kāi)始發(fā)送文件
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);
//關(guān)閉文件戳粒,關(guān)閉網(wǎng)絡(luò)描述符
}
return 0;
}