linux应用程序_1_文本浏览器_9_网络打印_1_TCP基本知识和例程
客户端:在网络程序中,主动和外面的程序通信
服务端:被动的等待外面的程序来和自己通讯
TCP(Transfer Control Protocol)传输控制协议是一种面向连接的协议, 当我们的网络程序使用这个协议的时候,网络可以保证我们的客户端和服务端的连接是可靠的,安全的。出现丢包现象时,会自动重连
基本调用:
int socket(int domain, int type,int protocol)
int bind(int sockfd, struct sockaddr *my_addr, int addrlen)
int listen(int sockfd,int backlog)
int accept(int sockfd, struct sockaddr *addr,int *addrlen)
int connect(int sockfd, struct sockaddr * serv_addr,int addrlen)
ssize_t send(int sockfd, const void *buf, size_t len, int flags)
ssize_t recv(int sockfd, void *buf, size_t len, int flags);
其中结构体声明有:
struct sockaddr{
unisgned short as_family;
char sa_data[14];
};
struct sockaddr_in{
unsigned short sin_family;
unsigned short int sin_port;
struct in_addr sin_addr;
unsigned char sin_zero[8];
}
由于系统的兼容性,一般使用后者
例程:
tcp_server.c
其中signal是为了避免出现僵尸进程
#include <sys/types.h>
#include <sys/socket.h>
#include <stdio.h>
#include <string.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <stdlib.h>
#include <errno.h>
#include <unistd.h>
#include <netdb.h>
#include <signal.h>
#define BACKLOG 10
#define SERVER_PORT 8888
int main(int argc,char **argv)
{
int iServerFd, iClientFd;
int iRet;
struct sockaddr_in tSocketServerAddr;
struct sockaddr_in tSocketClientAddr;
int iSocketAddrLen = sizeof(struct sockaddr);
char pcBuf[1024];
int iLen;
int iClientNum = 0;
signal(SIGCHLD,SIG_IGN);
iServerFd = socket(AF_INET, SOCK_STREAM, 0);
if(iServerFd < 0)
{
printf("socket error\r\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(iServerFd, (struct sockaddr *)&tSocketServerAddr, iSocketAddrLen);
if(iRet < 0)
{
printf("bind error\r\n");
goto error;
}
iRet = listen(iServerFd, BACKLOG);
if(iRet < 0)
{
printf("listen error\r\n");
return -1;
}
while(1)
{
iSocketAddrLen = sizeof(struct sockaddr);
iClientFd = accept(iServerFd, (struct sockaddr *)&tSocketClientAddr, &iSocketAddrLen);
if(iClientFd < 0)
{
printf("accept error\r\n");
return -1;
}
iClientNum++;
printf("connect with client %d %s\r\n", iClientNum, inet_ntoa(tSocketClientAddr.sin_addr));
if(!fork())
{
while(1)
{
iLen = recv(iClientFd, pcBuf, 1023, 0);
if(iLen <= 0)
{
close(iClientFd);
goto error;
}
else
{
pcBuf[iLen] = '\0';
printf("get msg %s from Client %d %s\r\n", pcBuf, iClientNum, inet_ntoa(tSocketClientAddr.sin_addr));
}
}
}
}
close(iServerFd);
return 0;
error:
close(iServerFd);
return -1;
}
tcp_client.c
#include <sys/types.h>
#include <sys/socket.h>
#include <stdio.h>
#include <string.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <stdlib.h>
#include <errno.h>
#include <unistd.h>
#include <netdb.h>
#define SERVER_PORT 8888
int main(int argc,char **argv)
{
int iServerFd, iClientFd;
int iRet;
struct sockaddr_in tSocketServerAddr;
int iSocketAddrLen = sizeof(struct sockaddr);
char pcBuf[1024];
int iLen;
if(argc != 2)
{
printf("Usage : %s <server_ip>\r\n", argv[0]);
return -1;
}
iClientFd = socket(AF_INET, SOCK_STREAM, 0);
if(iClientFd < 0)
{
printf("socket error\r\n");
return -1;
}
tSocketServerAddr.sin_family = AF_INET;
tSocketServerAddr.sin_port = htons(SERVER_PORT);
if(!inet_aton(argv[1], &tSocketServerAddr.sin_addr))
{
printf("ivalid server_ip\r\n");
goto error;
}
memset(tSocketServerAddr.sin_zero, 0, 8);
iRet = connect(iClientFd, (struct sockaddr *)&tSocketServerAddr, sizeof(struct sockaddr));
if(iRet < 0)
{
printf("connect error\r\n");
return -1;
}
while(1)
{
if(!fgets(pcBuf, 1023, stdin))
{
printf("fgets error\r\n");
goto error;
}
iLen = send(iClientFd, pcBuf, strlen(pcBuf), 0);
if(iLen <= 0)
{
printf("send error\r\n");
goto error;
}
}
close(iClientFd);
return 0;
error:
close(iClientFd);
return -1;
}