欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

Linux网络编程:socket编程(TCP、UDP)

程序员文章站 2022-06-30 09:17:36
...

TCP

TCP是面向连接字节流传输控制协议(面向连接就是互通之前先建立起连接),有验证重发机制,不会出现丢包或乱序;建立连接时有三次握手,取消连接时有四次挥手。三次握手就是两者进行一些约定,对格式的空间等信息进行传递。在用户层中提供的是数据,然后经过TCP协议添加了首部成为TCP段,再经过IP协议层添加了IP首部成为IP数据报,再到硬件驱动层添加以太网首部和以太网尾部成为以太网帧,TCP 报文头里面的序号能使 TCP 的数据按顺序到达;有累计确认及超时重传机制(时间加倍)。TCP主要传输重要数据(如文件),FTP属于TCP传输。
Linux网络编程:socket编程(TCP、UDP)

通信例程

服务器端

#include <sys/types.h>         
#include <sys/socket.h>
#include <string.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <stdio.h>
#include <signal.h>

#define SERVER_PORT 8888
#define BACKLOG 	10

int main(int argc,char **argv)
{
	int iSocketServer;
	int iSocketClient;
	struct sockaddr_in tSocketServerAddr;
	struct sockaddr_in tSocketClientAddr;
	int iRet;
	int iAddrLen;
	int iClientNum = -1;
	int iRecvLen;
	unsigned char ucRecvBuf[1000];
	
	
	signal(SIGCHLD,SIG_IGN);

	// 获得文件句柄
	iSocketServer = socket(AF_INET,SOCK_STREAM,0);
	if(-1 == iSocketServer)
	{
		printf("socket error!\n");
		return -1;
	}

	// 配置本地信息
	tSocketServerAddr.sin_family = AF_INET;			// Ipv4协议
	tSocketServerAddr.sin_port = htons(SERVER_PORT); // 设置端口
	tSocketServerAddr.sin_addr.s_addr = INADDR_ANY;	// 允许任何地址
	memset(tSocketServerAddr.sin_zero,0,8);

	// 传递前面构造的结构体
	iRet = bind(iSocketServer,
				(const struct sockaddr *)&tSocketServerAddr,
				sizeof(struct sockaddr));
	if(-1 == iRet)
	{
		printf("bind error!\n");
		return 0;
	}

	// 监听信息
	iRet = listen(iSocketServer,BACKLOG);
	if(-1 == iRet)
	{
		printf("listen error!\n");
		return -1;
	}
	
	while(1)
	{
		iAddrLen = sizeof(struct sockaddr);
		// 获取客户端信息
		iSocketClient = accept(iSocketServer,
						(struct sockaddr *)&tSocketClientAddr,
						&iAddrLen);
		if(-1 != iSocketClient)
		{
			iClientNum++;
			printf("Get connect from client %d : %s\n",
					iClientNum,
					inet_ntoa(tSocketClientAddr.sin_addr));
			if(!fork())
			{
				while(1)
				{
					// send/recv发送接收信息
					iRecvLen = recv(iSocketClient,ucRecvBuf,999,0);
					if(iRecvLen <= 0)
					{
						close(iSocketClient);
						return -1;
					}
					else
					{
						ucRecvBuf[iRecvLen]='\0';
						printf("Get Msg From Client %d : %s",
								iClientNum,ucRecvBuf);
					}
				}
			}
		}
	}
	close(iSocketClient);
	return 0;
}

客户端

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


#define SERVER_PORT 8888

int main(int argc,char **argv)
{
	int iSocketClient;
	struct sockaddr_in tSocketServerAddr;
	int iRet;
	unsigned char ucSendBuf[1000];
	int iSendlen;
	
	if(argc != 2)
	{
		printf("Usage:\n");
		printf("%s <server_ip>\n",argv[0]);
		return -1;
	}
	// 打开获得句柄
	iSocketClient = socket(AF_INET, SOCK_STREAM, 0);

	tSocketServerAddr.sin_family	 = AF_INET;
	tSocketServerAddr.sin_port		 = htons(SERVER_PORT);
	if(0 == inet_aton(argv[1],&tSocketServerAddr.sin_addr))
	{
		printf("invalid server_ip\n");
		return -1;
	}
	memset(tSocketServerAddr.sin_zero, 0, 8);

	// 与服务器端建立连接
	iRet = connect(iSocketClient, 
					(const struct sockaddr *)&tSocketServerAddr,
					sizeof(struct sockaddr));
	if(-1 == iRet)
	{
		printf("connect error!\n");
		return -1;
	}
	while(1)
	{
		if(fgets(ucSendBuf,999,stdin))
		{
			// 发送接收信息
			iSendlen = send(iSocketClient,
							ucSendBuf,strlen(ucSendBuf),0);
			if(iSendlen <= 0)
			{
				close(iSocketClient);
				return -1;
			}
		}
	}
	return 0;
}

UDP

UDP是无连接数据报服务,不对数据包进行检查、无需等待对方应答,会出现丢包乱序,但具有较好的实时性,比TCP结构简单,适用直播、游戏、物联网等实时性比较高的传输。TFTP、DHCP属于UDP的一种。
Linux网络编程:socket编程(TCP、UDP)

通信例程

服务器端

(注意对比一下TCP的例程)

#include <sys/types.h>         
#include <sys/socket.h>
#include <string.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <stdio.h>
#include <signal.h>

#define SERVER_PORT 8888

int main(int argc,char **argv)
{
	int iSocketServer;
	int iSocketClient;
	struct sockaddr_in tSocketServerAddr;
	struct sockaddr_in tSocketClientAddr;
	int iRet;
	int iAddrLen;
	int iClientNum = -1;
	int iRecvLen;
	unsigned char ucRecvBuf[1000];
	
	
	signal(SIGCHLD,SIG_IGN);

	// 打开获得句柄
	iSocketServer = socket(AF_INET,SOCK_DGRAM,0);
	if(-1 == iSocketServer)
	{
		printf("socket error!\n");
		return -1;
	}

	// 配置本地信息
	tSocketServerAddr.sin_family	  = AF_INET;
	tSocketServerAddr.sin_port		  = htons(SERVER_PORT);
	tSocketServerAddr.sin_addr.s_addr = INADDR_ANY;
	memset(tSocketServerAddr.sin_zero,0,8);

	// 传递前面构造的结构体
	iRet = bind(iSocketServer,
				(const struct sockaddr *)&tSocketServerAddr,
				sizeof(struct sockaddr));
	if(-1 == iRet)
	{
		printf("bind error!\n");
		return -1;
	}

	while(1)
	{
		iAddrLen = sizeof(struct sockaddr);
		
		// 发送/接收信息
		iRecvLen = recvfrom(iSocketServer, ucRecvBuf, 999, 0, 
					(struct sockaddr *)&tSocketClientAddr, &iAddrLen);
		if(iRecvLen > 0)
		{
			ucRecvBuf[iRecvLen] = '\0';
			printf("Get Msg From %s : %s\n", 
					inet_ntoa(tSocketClientAddr.sin_addr), ucRecvBuf);
		}
		
	}
	close(iSocketClient);
	return 0;
}

客户端

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

#define SERVER_PORT 8888

int main(int argc,char **argv)
{
	int iSocketClient;
	struct sockaddr_in tSocketServerAddr;
	int iRet;
	unsigned char ucSendBuf[1000];
	int iSendLen;
	int iAddrLen;
	
	if(argc != 2)
	{
		printf("Usage:\n");
		printf("%s <server_ip>\n",argv[0]);
		return -1;
	}
	// 打开获得句柄
	iSocketClient = socket(AF_INET, SOCK_DGRAM, 0);

	tSocketServerAddr.sin_family	 = AF_INET;
	tSocketServerAddr.sin_port		 = htons(SERVER_PORT);
	if(0 == inet_aton(argv[1],&tSocketServerAddr.sin_addr))
	{
		printf("invalid server_ip\n");
		return -1;
	}
	memset(tSocketServerAddr.sin_zero, 0, 8);

	while(1)
	{
		if(fgets(ucSendBuf,999,stdin))
		{
			iAddrLen = sizeof(struct sockaddr);
			
			// 发送/接收信息
			iSendLen = sendto(iSocketClient, ucSendBuf, 
								strlen(ucSendBuf), 0, 
							(const struct sockaddr *)&tSocketServerAddr, 
								iAddrLen);
			if(iSendLen <= 0)
			{
				close(iSocketClient);
				return -1;
			}
		}
	}
	return 0;
}