Linux TCP客户端、服务器编程模型及实例
2016-12-05 20:17
495 查看
Linux TCP客户端、服务器编程模型及实例
服务器模型:1、绑定IPv4的地址(INADDR_ANY)和端口号(8888)
int listenfd, sockfd, opt = 1;
struct sockaddr_in server, client;
新建socket
listenfd = socket(AF_INET, SOCK_STREAM, 0);
if(listenfd < 0){
perror("Create socket fail.");
return -1;
}
设置地址可重用功能,防止异常退出无法短时间打开server
if((ret = setsockopt(listenfd, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt))) < 0)
{
perror("Error, set socket reuse addr failed");
return -1;
}
bzero(&server, sizeof(server));
server.sin_family = AF_INET;
server.sin_port = htons(8888);
server.sin_addr.s_addr = htonl(INADDR_ANY);
2、将套接字转换成监听套接字
len = sizeof(struct sockaddr);
if(bind(listenfd, (struct sockaddr *)&server, len)<0){
perror("bind error.");
return -1;
}
listen(listenfd, MAX_LISTEN_QUE);
3、等待客户端连接
sockfd = accept(listenfd, (struct sockaddr *)&client, &len);
if(sockfd < 0)
{
perror("accept error.");
return -1;
}
4、读取客户端数据
read(sockfd,buf,100);
printf("%s\n",buf);
5、写据给客户端
time_now = time(NULL);
bzero(&buf,100);
strcpy(buf,(char *)ctime(&time_now));
printf("time:%s\n",buf);
write(sockfd,buf,strlen(buf));
6、关闭套接字
close(sockfd);
close(listenfd);
实例代码:
头文件apue.h
#include<stdio.h> #include<stdlib.h> #include<errno.h> #include<string.h> #include<strings.h> #include<time.h> #include<sys/socket.h> #include<sys/types.h> #include<netinet/in.h> #include<arpa/inet.h> //inet
源文件3.c
/************************************************************************* > File Name: 3.c > Created Time: 2016年12月01日 星期四 10时53分36秒 ************************************************************************/ /* *this is time server * */ #include"apue.h" #define MAX_LISTEN 10 int main(int argc,char *argv[]) { int listenfd,sockfd,opt = 1; struct sockaddr_in server,client; int len; time_t time_now; char buf[100]; listenfd = socket(AF_INET,SOCK_STREAM,0); if(listenfd<0) { perror("create socket failed\n"); return -1; } if(setsockopt(listenfd,SOL_SOCKET,SO_REUSEADDR,&opt,sizeof(opt))<0) { perror("set socket reuse addr failed\n"); return -1; } bzero(&server,sizeof(server)); server.sin_family = AF_INET; server.sin_port = htons(8888); server.sin_addr.s_addr = htonl(INADDR_ANY);//代表该主机上的所有IP地址,如果机器上有多个网卡或者虚拟机的话,若不使用此方法容易出错 len = sizeof(struct sockaddr); if(bind(listenfd,(struct sockaddr *)&server,len)<0) { perror("bind error\n"); return -1; } listen(listenfd,MAX_LISTEN);//可以连接的最大数据 while(1) //迭代服务器,同时不能连接多个客户端,当一个客户端关闭后就可以重新连接第二个客户端 { sockfd = accept(listenfd,(struct sockaddr *)&client,&len);//sockaddr 和sockaddr_in可以相互转化的 if(sockfd<0) { perror("accept error\n"); return -1; } read(sockfd,buf,100); printf("%s\n",buf); time_now = time(NULL); bzero(&buf,100); strcpy(buf,(char *)ctime(&time_now)); printf("time:%s\n",buf); write(sockfd,buf,strlen(buf)); printf("sockfd:%d\n",sockfd); close(sockfd); } close(listenfd); return 0; }
客户端模型:
1、创建一个IPv4(AF_INET)的字节流(SOCK_STREAM)套接字
int sockfd;
struct sockaddr_in server_ip;
if((sockfd = socket(AF_INET,SOCK_STREAM,0))<0)
{
perror("socket error\n");
return -1;
}
2、连接到IP地址为(192.168.1.108、127.0.0.1),端口号为8888的服务器
bzero(&server_ip,sizeof(server_ip));
//equal to memset()
server_ip.sin_family =AF_INET;
server_ip.sin_addr.s_addr = inet_addr("127.0.0.1");
server_ip.sin_port = htons(5678);
if(connect(sockfd,(struct sockaddr*)&server_ip,sizeof(server_ip))<0)
{
perror("connect error\n");
return 0;
}
3、写一个数据到服务器
strcpy(buf,(char *)"I am client");
if(write(sockfd,buf,strlen(buf))<0)
{
printf("error,write error\n");
return -1;
}
4、接收服务器传回来的数据并显示到标准输出
bytes = read(sockfd,buf,100);
if(bytes<0)
{
printf("error,read failed\n");
return -1;
}
5、关闭套接字
close(sockfd);
实例代码:
头文件同上;
源文件2.c
/************************************************************************* > File Name: 2.c > Created Time: 2016年12月01日 星期四 09时52分46秒 ************************************************************************/ /* *this is client to get server time * */ #include"apue.h" int main(int agtc,char *argv[]) { int sockfd; struct sockaddr_in server_ip; char buf[100]; int bytes; if((sockfd = socket(AF_INET,SOCK_STREAM,0))<0) { perror("socket error\n"); return -1; } bzero(&server_ip,sizeof(server_ip)); //equal to memser() server_ip.sin_family =AF_INET; server_ip.sin_addr.s_addr = inet_addr("127.0.0.1"); server_ip.sin_port = htons(8888); if(connect(sockfd,(struct sockaddr*)&server_ip,sizeof(server_ip))<0) { perror("connect error\n"); return 0; } bzero(&buf,100); strcpy(buf,(char *)"I am client"); if(write(sockfd,buf,strlen(buf))<0) { printf("error,write error\n"); return -1; } bzero(&buf,100); bytes = read(sockfd,buf,100); if(bytes<0) { printf("error,read failed\n"); return -1; } if(bytes ==0) { printf("Server close connection\n"); return -1; } if(bytes >0) { printf("read bytes %d\n",bytes); printf("time is %s\n",buf); } close(sockfd); return 0; }
注意:server中添加了setsockopt函数
#include <sys/types.h>
#include <sys/socket.h>
int setsockopt(int sockfd, int level, int optname,const void *optval, socklen_t optlen);
如果运行server的时候,若未正常退出内核有时候会提示地址已经在使用,此时可用此函数来重用地址,否则在几分钟内无法重启server的。
相关文章推荐
- linux-socket tcp客户端服务器编程模型及代码详解
- linux tcp多线程服务器与客户端编程实例
- Linux高级编程复习 第十章 TCP编程模型_TCP通信特点_TCP多进程服务器
- 【Linux网络编程】基于TCP协议 I/O多路转接(select) 的高性能回显服务器客户端模型
- Linux基于TCP/IP简单的客户端、服务器通信程序实例
- Linux网络编程 之 TCP 多线程的服务器和客户端同时收发数据
- linux网络编程--服务器客户端(TCP实现)
- 【Linux网络编程】基于TCP多进程(fork)版本客户端/服务器
- TCP/TP编程 - 一个简单的Linux下C写的socket服务器客户端程序
- Linux基于TCP/IP简单的客户端、服务器通信程序实例
- 【Linux网络编程】基于TCP单进程版本阻塞式客户端/服务器
- Linux下的C语言编程——简单实现tcp客户端和服务器
- 基于linux poll模型的tcp服务器------一个服务器如何与多个客户端进行通信?
- Linux网络编程 3 - 简单的Tcp服务器和客户端编程
- Linux网络编程[UDP客户端服务器的编程模型]
- Linux网络编程【六】:TCP协议高性能服务器(http)模型之I/O多路转接epoll
- Linux Socket编程:基于TCP/IP的客户端与服务端通讯实例
- linux下网络编程2:服务端和客户端进行TCP通信实例
- 【Linux网络编程实例】实例二:利用TCP协议进行客户端与服务器通信
- WINDOWS (服务器) 和 DOS(客户端) 网络互连 基于TCP/IP的编程实现