Liunx - 网络编程

Liunx - 网络编程

一 基础知识

1. TCP / UDP

  1. TCP面向连接(如打电话要先拨号建立连接);UDP是无连接的,即发送数据之前不需要建立连接。
  2. TCP提供可靠的服务。也就是说,通过TCP连接传送的数据,无差错,不丢失,不重复,且按序到达;UDP尽最大努力交付,即不保证可靠交付
  3. TCP面向字节流,实际上是TCP把数据看成一连串无结构的字节流;UDP是面向报文的UDP没有拥塞控制,因此网络出现拥塞不会使源主机的发送速率降低(对实时应用很有用,如IP电话,实时视频会议等)
  4. 每一条TCP连接只能是点到点的;UDP支持一对一,一对多,多对一和多对多的交互通信。
  5. TCP首部开销20字节;UDP的首部开销小,只有8个字节。
  6. TCP的逻辑通信信道是全双工的可靠信道,UDP则是不可靠信道。

2. 端口

一台拥有IP地址的主机可以提供许多服务,比如Web服务、FTP服务、SMTP服务等
这些服务完全可以通过1个IP地址来实现。那么,主机是怎样区分不同的网络服务呢?显然不能只靠IP地址,因为IP 地址与网络服务的关系是一对多的关系。
实际上是通过“IP地址+端口号”来区 分不同的服务的。端口提供了一种访问通道,服务器一般都是通过知名端口号来识别的。例如,对于每个TCP/IP实现来说,FTP服务器的TCP端口号都是21,每个Telnet服务器的TCP端口号都是23,每个TFTP(简单文件传送协议)服务器的UDP端口号都是69

3. 字节序

  1. Little endian(小端字节序):将低序字节存储在起始地址
  2. Big endian(大端字节序):将高序字节存储在起始地址

二 代码实现

1. 编程思路

1.1 服务器
  1. 表名身份(服务器)
  2. 连接方式(TCP / UDP)
  3. IP 地址
  4. 端口
  5. 等待访问
1.2 客户端
  1. 获取服务器 IP
  2. 获取服务器端口连接

2. 相关 API

3. socket 服务器端 / 客户端 开发步骤

  1. 创建套接字
  2. 套接字添加信息 (IP 地址 和 端口 )
  3. 监听网络连接
  4. 监听到有客户端接入,接受连接
  5. 数据交互
  6. 关闭套接字,关闭连接

4. 代码实现

服务端

#include <stdio.h>
#include <sys/types.h>          /* See NOTES */
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
// 服务端
int main(int argc,char **argv){
	int s_fd ; 
	int c_fd ;
	int n_read ;
	
	char sendBuf[128] = "welcome!!!"; 
	char readBuf[128] = {0}; 
	
	struct sockaddr_in s_addr ; 
	struct sockaddr_in c_addr ; 
	
	memset(&s_addr , 0 , sizeof(struct sockaddr_in));	
	memset(&c_addr , 0 , sizeof(struct sockaddr_in));
	if(argc != 3 ){
		perror("argc");
	}

	// 1. socket
	s_fd =  socket(AF_INET,SOCK_STREAM,0);	
	if(s_fd == -1 ){
		perror("socket");
		exit(-1);
	}	
	// 2. bind 
	s_addr.sin_family = AF_INET;
	s_addr.sin_port = htons(atoi(argv[2]));
	inet_aton(argv[1],&s_addr.sin_addr);
	
	bind(s_fd,(struct sockaddr *)&s_addr,sizeof(struct sockaddr_in));
	// 3. listen 
	listen(s_fd,10);	
	
	while(1){
		
		// 4. accept 
		int clen = sizeof(struct sockaddr_in);
		c_fd = accept(s_fd,(struct sockaddr *)&c_addr,&clen);
		
		if(c_fd == -1 ){
			perror("accept\n");
			exit(-1);
		}	
		if(fork() == 0 ){
			while(1){
					
				// 6. write	
				// char* msg = "welcome !!!  \n" ;	
				printf("client ip is %s ",inet_ntoa(c_addr.sin_addr));	
				printf(">");
				gets(sendBuf);
				write(c_fd , sendBuf,strlen(sendBuf));
				printf("\n");
			
			}
		}		

		if(fork() == 0){
			while(1){	
				// 5. read  
				memset(readBuf,0,sizeof(readBuf));
				n_read =  read(c_fd,readBuf,128);		
				if(n_read == -1 ){
					perror("read");
					exit(-1);
				}else{
					printf("mess is %s\n",readBuf);
				}
			}			
		}	
		
	}
	return 1 ; 
}

客户端

#include <stdio.h>
#include <sys/types.h>          /* See NOTES */
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>

int main(int argc , char **argv){
	int c_fd; 	
	int n_read;
	char readBuf[128];
	//char* msg = "hello this is laopi server \n" ;
	char sendBuf[128] = {0};
	struct sockaddr_in c_addr ; 
	
	memset(&c_addr , 0 , sizeof(struct sockaddr_in));
	if(argc != 3){
		perror("argc");
	}
	// 1. socket
	c_fd =  socket(AF_INET,SOCK_STREAM,0);	
	if(c_fd == -1 ){
		perror("socket\n");
		exit(-1);
	}

	c_addr.sin_family = AF_INET ; 
	c_addr.sin_port = htons(atoi(argv[2]));
	inet_aton(argv[1],&c_addr.sin_addr);
	// 2. connect 
	if(connect(c_fd,(struct sockaddr *)&c_addr,sizeof(struct sockaddr)) == -1)	
	{
		perror("connect\n");
		exit(-1);
	}
	
		if(fork() == 0 ){
			while(1){
				// 5. read  
				memset(readBuf,0,128);
				n_read =  read(c_fd,readBuf,128);		
				if(n_read == -1 ){
					perror("read");
					exit(-1);
				}else{
					printf("server %s  port %s : %s \n",argv[1],argv[2],readBuf);
				}
			}
		}

	while(1){
		memset(sendBuf,0,sizeof(sendBuf));
		printf(">");
		gets(sendBuf);
		// 3.send 
		write(c_fd ,sendBuf,strlen(sendBuf));
		printf("\n");
	}
	return 1 ; 
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

老痞啥都不会

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值