Linux下socket编程之TCP简单实现
2017-05-02 14:35
645 查看
本文主要是简单的实现一个Linux下TCP网络编程的小例子。总共分为两个部分:客服端的实现和服务器端的实现。实现的功能很简单,当客服端和服务器端绑定之后,通过在客服端输入一个字符串,服务器将客服端输入的字符串进行相应的输出。
一、服务器端的实现
1、打开一个socket设备,获得socket设备的文件描述符,指定网络协议和传输类型
/* 1、获得服务器端的socket文件描述符 */
iSocketServerFd = socket(AF_INET, SOCK_STREAM, 0); // 网络协议是ipv4,传输方式为tcp
if(iSocketServerFd == -1)
{
printf("socket error!\n");
return -1;
} 2、绑定
主要是将第一步获得的文件描述符与具体的服务器端进行绑定,包括网络的协议、端口号、对客服端的访问限制等。
/* 2、对服务器端进行绑定 */
/* 2.1 设置服务器端的socket地址描述结构体 */
tSocketServerAddr.sin_family = AF_INET; // 网络协议是ipv4
tSocketServerAddr.sin_port = htons(SOCKET_PORT); // socket的端口号
tSocketServerAddr.sin_addr.s_addr = htonl(INADDR_ANY); // 客服端的地址可以是任意的
memset(tSocketServerAddr.sin_zero, 0, 8);
iSockAddrLen = sizeof(struct sockaddr); // 获得这个结构体的大小
/* 2.2 绑定 */
iRet = bind(iSocketServerFd, (const struct sockaddr *)&tSocketServerAddr, iSockAddrLen);
if(iRet == -1)
{
printf("bind error!\n");
return -1;
} 3、监听
对客服端进行监听。
/* 3、服务器端进行监听 */
iRet = listen(iSocketServerFd, LISTEN_BACKLOG);
if(iRet == -1)
{
printf("listen error!\n");
return -1;
} 4、accept
/* 4、接收一个客服端的socket的连接 */
iSocketClientFd = accept(iSocketServerFd, (struct sockaddr *)&tSocketClientAddr, &iSockAddrLen);
if(iSocketClientFd < 0)
{
printf("accept error!\n");
return -1;
}
5、接收和发送数据
/* 接收从客服端传送过来的数据 */
iRecvLen = recv(iSocketClientFd, ucRecvBuf, ARRAY_LENGTH, 0);
服务器端的完整实现代码如下:
二、客服端的实现
1、打开一个socket设备,获得设备描述符,指定网络协议和传输类型
/* 1、获得客服端的socket文件描述符 */
iSocketClientFd = socket(AF_INET, SOCK_STREAM, 0); // 网络协议是ipv4,传输类型为tcp
if(iSocketClientFd == -1)
{
printf("socket error!\n");
return -1;
} 2、connect
将客服端和服务器端连接起来。/* 2、初始化一个客服端和服务器之间的连接 */
/* 2.1 设置所连接的服务器 */
tSocketServerAddr.sin_family = AF_INET; // 协议是ipv4
tSocketServerAddr.sin_port = htons(SOCKET_PORT); // 绑定的端口
iRet = inet_aton(argv[1], &tSocketServerAddr.sin_addr); // 获得的ip地址
if(iRet == 0)
{
printf("server ip is not valid!\n");
return -1;
}
memset(tSocketServerAddr.sin_zero, 0, 8);
iSockAddrLen = sizeof(struct sockaddr);
/* 2.2 将客服端和服务器进行连接 */
iRet = connect(iSocketClientFd, (const struct sockaddr *)&tSocketServerAddr, iSockAddrLen);
if(iRet == -1)
{
printf("connect error!\n");
return -1;
}
3、接收和发送数据
if(fgets(ucSendBuf, ARRAY_LENGTH, stdin)) // 从用户输入获得一个字符串
{
/* 向客服端发送用户输入的信息 */
iSendLen = send(iSocketClientFd, ucSendBuf, strlen(ucSendBuf), 0);
if(iSendLen <= 0)
{
printf("send error!\n");
close(iSocketClientFd);
return -1;
}
}客服端的完整实现代码如下:
三、测试
由于本实例涉及到客服端和服务器,所以需要分别运行。可以在同一台电脑上进行测试,通过不同的终端来实现;也可以在不同的电脑上进行测试,只要在同一个局域网中即可。本次测试使用第一种方式进行。
测试结果如下:
客服端:
![](https://img-blog.csdn.net/20170502145616036?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvVEVDSF9QUk8=/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center)
服务器端:
![](https://img-blog.csdn.net/20170502145633745?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvVEVDSF9QUk8=/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center)
通过上面测试结果可以看出,每当在客服端输入一串字符串时,在相应的服务器端也会有同样的输出。
一、服务器端的实现
1、打开一个socket设备,获得socket设备的文件描述符,指定网络协议和传输类型
/* 1、获得服务器端的socket文件描述符 */
iSocketServerFd = socket(AF_INET, SOCK_STREAM, 0); // 网络协议是ipv4,传输方式为tcp
if(iSocketServerFd == -1)
{
printf("socket error!\n");
return -1;
} 2、绑定
主要是将第一步获得的文件描述符与具体的服务器端进行绑定,包括网络的协议、端口号、对客服端的访问限制等。
/* 2、对服务器端进行绑定 */
/* 2.1 设置服务器端的socket地址描述结构体 */
tSocketServerAddr.sin_family = AF_INET; // 网络协议是ipv4
tSocketServerAddr.sin_port = htons(SOCKET_PORT); // socket的端口号
tSocketServerAddr.sin_addr.s_addr = htonl(INADDR_ANY); // 客服端的地址可以是任意的
memset(tSocketServerAddr.sin_zero, 0, 8);
iSockAddrLen = sizeof(struct sockaddr); // 获得这个结构体的大小
/* 2.2 绑定 */
iRet = bind(iSocketServerFd, (const struct sockaddr *)&tSocketServerAddr, iSockAddrLen);
if(iRet == -1)
{
printf("bind error!\n");
return -1;
} 3、监听
对客服端进行监听。
/* 3、服务器端进行监听 */
iRet = listen(iSocketServerFd, LISTEN_BACKLOG);
if(iRet == -1)
{
printf("listen error!\n");
return -1;
} 4、accept
/* 4、接收一个客服端的socket的连接 */
iSocketClientFd = accept(iSocketServerFd, (struct sockaddr *)&tSocketClientAddr, &iSockAddrLen);
if(iSocketClientFd < 0)
{
printf("accept error!\n");
return -1;
}
5、接收和发送数据
/* 接收从客服端传送过来的数据 */
iRecvLen = recv(iSocketClientFd, ucRecvBuf, ARRAY_LENGTH, 0);
服务器端的完整实现代码如下:
#include <stdio.h> #include <sys/types.h> /* See NOTES */ #include <sys/socket.h> #include <string.h> #include <netinet/in.h> #include <arpa/inet.h> #include <signal.h> #define SOCKET_PORT 1234 // 定义端口,与指定的socket绑定 #define LISTEN_BACKLOG 10 // 最大监听的客服端数量 #define ARRAY_LENGTH 256 // 接收缓冲区的大小 /* 程序的入口函数 */ int main(void) { int iSocketServerFd; // 定义服务器的文件描述符 int iSocketClientFd; // 定义客服端的文件描述符 struct sockaddr_in tSocketServerAddr; // 服务器socket地址的描述结构体定义 struct sockaddr_in tSocketClientAddr; // 客服端socket地址的描述结构体定义 int iSockAddrLen; int iRet; unsigned char ucRecvBuf[ARRAY_LENGTH]; // 定义接收数据的缓冲区 int iRecvLen; int client_flag = 0; signal(SIGCHLD,SIG_IGN); /* 1、获得服务器端的socket文件描述符 */ iSocketServerFd = socket(AF_INET, SOCK_STREAM, 0); // 网络协议是ipv4,传输方式为tcp if(iSocketServerFd == -1) { printf("socket error!\n"); return -1; } /* 2、对服务器端进行绑定 */ /* 2.1 设置服务器端的socket地址描述结构体 */ tSocketServerAddr.sin_family = AF_INET; // 网络协议是ipv4 tSocketServerAddr.sin_port = htons(SOCKET_PORT); // socket的端口号 tSocketServerAddr.sin_addr.s_addr = htonl(INADDR_ANY); // 客服端的地址可以是任意的 memset(tSocketServerAddr.sin_zero, 0, 8); iSockAddrLen = sizeof(struct sockaddr); // 获得这个结构体的大小 /* 2.2 绑定 */ iRet = bind(iSocketServerFd, (const struct sockaddr *)&tSocketServerAddr, iSockAddrLen); if(iRet == -1) { printf("bind error!\n"); return -1; } /* 3、服务器端进行监听 */ iRet = listen(iSocketServerFd, LISTEN_BACKLOG); if(iRet == -1) { printf("listen error!\n"); return -1; } while(1) { /* 4、接收一个客服端的socket的连接 */ iSocketClientFd = accept(iSocketServerFd, (struct sockaddr *)&tSocketClientAddr, &iSockAddrLen); if(iSocketClientFd < 0) { printf("accept error!\n"); return -1; } client_flag = client_flag + 1; // 更新标志位 /* 连接成功,打印出客服端的ip地址 */ printf("client %d : %s has connected\n", client_flag, inet_ntoa(tSocketClientAddr.sin_addr)); if(fork() == 0) /*创建子进程*/ { while(1) { /* 接收从客服端传送过来的数据 */ iRecvLen = recv(iSocketClientFd, ucRecvBuf, ARRAY_LENGTH, 0); if(iRecvLen <= 0) { close(iSocketClientFd); return -1; } else { ucRecvBuf[iRecvLen] = '\0'; printf("client %d : %s", client_flag, ucRecvBuf); } } } } close(iSocketServerFd); return 0; }
二、客服端的实现
1、打开一个socket设备,获得设备描述符,指定网络协议和传输类型
/* 1、获得客服端的socket文件描述符 */
iSocketClientFd = socket(AF_INET, SOCK_STREAM, 0); // 网络协议是ipv4,传输类型为tcp
if(iSocketClientFd == -1)
{
printf("socket error!\n");
return -1;
} 2、connect
将客服端和服务器端连接起来。/* 2、初始化一个客服端和服务器之间的连接 */
/* 2.1 设置所连接的服务器 */
tSocketServerAddr.sin_family = AF_INET; // 协议是ipv4
tSocketServerAddr.sin_port = htons(SOCKET_PORT); // 绑定的端口
iRet = inet_aton(argv[1], &tSocketServerAddr.sin_addr); // 获得的ip地址
if(iRet == 0)
{
printf("server ip is not valid!\n");
return -1;
}
memset(tSocketServerAddr.sin_zero, 0, 8);
iSockAddrLen = sizeof(struct sockaddr);
/* 2.2 将客服端和服务器进行连接 */
iRet = connect(iSocketClientFd, (const struct sockaddr *)&tSocketServerAddr, iSockAddrLen);
if(iRet == -1)
{
printf("connect error!\n");
return -1;
}
3、接收和发送数据
if(fgets(ucSendBuf, ARRAY_LENGTH, stdin)) // 从用户输入获得一个字符串
{
/* 向客服端发送用户输入的信息 */
iSendLen = send(iSocketClientFd, ucSendBuf, strlen(ucSendBuf), 0);
if(iSendLen <= 0)
{
printf("send error!\n");
close(iSocketClientFd);
return -1;
}
}客服端的完整实现代码如下:
#include <stdio.h> #include <sys/types.h> /* See NOTES */ #include <sys/socket.h> #include <string.h> #include <netinet/in.h> #include <arpa/inet.h> #define SOCKET_PORT 1234 // 定义socket端口,用于可服务器端进行绑定 #define ARRAY_LENGTH 256 // 发送缓冲区的大小 int main(int argc, char **argv) { int iSocketClientFd; // 定义一个客服端的socket文件描述符 struct sockaddr_in tSocketServerAddr; // 定义一个服务器端的socket地址描述结构体变量 int iSockAddrLen; int iSendLen; unsigned char ucSendBuf[ARRAY_LENGTH]; // 定义缓冲区 int iRet; if(argc != 2) { printf("Usage :\n"); printf("%s <server_ip>\n", argv[0]); return -1; } /* 1、获得客服端的socket文件描述符 */ iSocketClientFd = socket(AF_INET 4000 , SOCK_STREAM, 0); // 网络协议是ipv4,传输类型为tcp if(iSocketClientFd == -1) { printf("socket error!\n"); return -1; } /* 2、初始化一个客服端和服务器之间的连接 */ /* 2.1 设置所连接的服务器 */ tSocketServerAddr.sin_family = AF_INET; // 协议是ipv4 tSocketServerAddr.sin_port = htons(SOCKET_PORT); // 绑定的端口 iRet = inet_aton(argv[1], &tSocketServerAddr.sin_addr); // 获得的ip地址 if(iRet == 0) { printf("server ip is not valid!\n"); return -1; } memset(tSocketServerAddr.sin_zero, 0, 8); iSockAddrLen = sizeof(struct sockaddr); /* 2.2 将客服端和服务器进行连接 */ iRet = connect(iSocketClientFd, (const struct sockaddr *)&tSocketServerAddr, iSockAddrLen); if(iRet == -1) { printf("connect error!\n"); return -1; } printf("Input a message to %s: \n", argv[1]); while(1) { if(fgets(ucSendBuf, ARRAY_LENGTH, stdin)) // 从用户输入获得一个字符串 { /* 向客服端发送用户输入的信息 */ iSendLen = send(iSocketClientFd, ucSendBuf, strlen(ucSendBuf), 0); if(iSendLen <= 0) { printf("send error!\n"); close(iSocketClientFd); return -1; } } } close(iSocketClientFd); return 0; }
三、测试
由于本实例涉及到客服端和服务器,所以需要分别运行。可以在同一台电脑上进行测试,通过不同的终端来实现;也可以在不同的电脑上进行测试,只要在同一个局域网中即可。本次测试使用第一种方式进行。
测试结果如下:
客服端:
服务器端:
通过上面测试结果可以看出,每当在客服端输入一串字符串时,在相应的服务器端也会有同样的输出。
相关文章推荐
- 简单的IPv6 UDP/TCP socket编程 -- 两台Linux实现简单的ipv6通信
- 简单的-TCP服务端 - Linux socket编程入门(1)
- TCP Linux socket编程实现两个正整数的加法
- socket 编程 TCP 实现简单聊天功能【转】
- Linux socket编程示例(最简单的TCP和UDP两个例子)
- unix/linux socket 编程一,简单多进程tcp socket server流程
- Linux Socket 事件触发模型 epoll 示例 这里会写一个用C语言的TCP服务器的完全实现的简单程序
- Linux网络编程之socket简单通信TCP--服务端代码
- Linux C TCPSocket 传输文件简单实例-多线程实现
- socket编程实现简单DNS协议实现获取域名ip(TCP)
- socket 编程 TCP 实现简单聊天功能
- linux socket编程以及简单的tcp,udp的例子
- linux下socket实现TCP通信的简单程序接口封装
- python socket编程实现的简单tcp迭代server
- Linux C Socket编程原理及tcp, udp简单实例
- Linux网络编程 - TCP Socket 简单练习:新进程辅助通信
- linux下第一个socket编程实现的局域网内通信(基于TCP)
- Linux socket编程入门及客户端服务器端通信实现 – 提高篇:TCP连接过程分析
- 【原创】TCP Socket 简单练习 --- 线程池实现并发服务器 分类: Linux --- 应用程序设计 2014-12-25 13:59 50人阅读 评论(0) 收藏
- linux网络编程之用socket实现简单客户端和服务端的通信(基于UDP)