Linux网络编程:socket编程(TCP、UDP)
程序员文章站
2022-06-30 09:17:36
...
TCP
TCP是面向连接的字节流传输控制协议(面向连接就是互通之前先建立起连接),有验证重发机制,不会出现丢包或乱序;建立连接时有三次握手,取消连接时有四次挥手。三次握手就是两者进行一些约定,对格式的空间等信息进行传递。在用户层中提供的是数据,然后经过TCP协议添加了首部成为TCP段,再经过IP协议层添加了IP首部成为IP数据报,再到硬件驱动层添加以太网首部和以太网尾部成为以太网帧,TCP 报文头里面的序号能使 TCP 的数据按顺序到达;有累计确认及超时重传机制(时间加倍)。TCP主要传输重要数据(如文件),FTP属于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
#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的一种。
通信例程
服务器端
(注意对比一下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;
}
上一篇: 基于UDP协议实现多人聊天室
下一篇: 网络通信-udp