您的位置:首页 > 理论基础 > 计算机网络

Socket编程下篇-----TCP协议的C/S案例

2017-07-10 11:20 239 查看
一共有4个源码文件组成。

tcp_net_socket.h源码:

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

extern int tcp_init(const char* ip, int port);
extern int tcp_accept(int sfd);
extern int tcp_connect(const char* ip, int port);
extern void signalhandler(void);
#endif


tcp_net_socket.c源码:

#include "tcp_net_socket.h"

//用于初始化,返回一个经过bind、listen处理以后的socket
int tcp_init(const char* ip, int port)
{
//首先创建一个Socket,向系统申请
int sfd = socket(AF_INET, SOCK_STREAM, 0);
if(sfd == -1)
{
perror("server socket");
exit(-1);
}

struct sockaddr_in serveraddr;
memset(&serveraddr, 0, sizeof(struct sockaddr));
serveraddr.sin_family = AF_INET;
serveraddr.sin_port = htons(port);
serveraddr.sin_addr.s_addr = inet_addr(ip);

//将新的socket与指定的ip、port绑定
if(bind(sfd, (struct sockaddr*)&serveraddr, sizeof(struct sockaddr))==-1)
{
perror("bind");
close(sfd);
exit(-1);
}

//监听它,并设置其允许最大的连接数为10个
if(listen(sfd, 10) == -1)
{
perror("listen");
close(sfd);
exit(-1);
}
return sfd;
}

//用于服务端的接收,返回一个经过accept处理以后的new_fd
int tcp_accept(int sfd)
{
struct sockaddr_in clientaddr;
memset(&clientaddr, 0, sizeof(struct sockaddr));
int addrlen = sizeof(struct sockaddr);
int new_fd = accept(sfd, (struct sockaddr*)&clientaddr, &addrlen);
//sfd接受客户端连接,并创建新的socket为new_fd,将请求连接的客户端的IP、port保存在结构体clientaddr中
if(new_fd == -1)
{
perror("accept");
close(sfd);
exit(-1);
}
printf("success connect......\n");
return new_fd;
}

//用于客户端连接
int tcp_connect(const char* ip, int port)
{
int sfd = socket(AF_INET, SOCK_STREAM, 0);
if(sfd == -1)
{
perror("client socket");
exit(-1);
}

struct sockaddr_in serveraddr;
memset(&serveraddr, 0, sizeof(struct sockaddr));
serveraddr.sin_family = AF_INET;
serveraddr.sin_port = htons(port);
serveraddr.sin_addr.s_addr = inet_addr(ip);
//将sfd连接到指定服务器网络地址serveraddr
if(connect(sfd, (struct sockaddr*)&serveraddr, sizeof(struct sockaddr))==-1)
{
perror("connect");
close(sfd);
exit(-1);
}
return sfd;
}

//用于信号处理,让服务端在按下Ctrl+c或Ctrl+\时不会退出
void signalhandler(void)
{
sigset_t sigSet;
sigemptyset(&sigSet);
sigaddset(&sigSet, SIGINT);
sigaddset(&sigSet, SIGQUIT);
sigprocmask(SIG_BLOCK, &sigSet, NULL);
}


tcp_net_server.c源码:

#include "tcp_net_socket.h"

int main(int argc, char* argv[])
{
if(argc < 3)
{
printf("用法:./tcp_net_server ip port\n");
exit(-1);
}

signalhandler();
int sfd = tcp_init(argv[1], atoi(argv[2]));

//用while循环表示可以与多个客户端接收和发送,但是仍是阻塞模式
while(1)
{
int connected_fd = tcp_accept(sfd);
char buf[512] = {0};
//从connected_fd客户端接收数据存储于buf中
if(recv(connected_fd, buf, sizeof(buf), 0)==-1)
{
perror("server recv");
close(connected_fd);
close(sfd);
exit(-1);
}
puts(buf);
//向connected_fd客户端发送hello world数据
if(send(connected_fd, "hello world", 12, 0) == -1)
{
perror("server send");
close(connected_fd);
close(sfd);
exit(-1);
}
//每个客户端完成一次发送接收,就把客户端连接资源释放。
close(connected_fd);
}
close(sfd);
return 0;
}


tcp_net_client.c源码:

#include "tcp_net_socket.h"

int main(int argc, char* argv[])
{
if(argc < 3)
{
printf("用法:./tcp_net_client ip port\n");
exit(-1);
}

int sfd = tcp_connect(argv[1], atoi(argv[2]));
char buf[512] = {0};
send(sfd, "hello", 6, 0);
recv(sfd, buf, sizeof
b394
(buf), 0);
puts(buf);
close(sfd);
}


调试程序:

//编译程序
gcc -o tcp_net_server tcp_net_server.c tcp_net_socket.c
gcc -o tcp_net_client tcp_net_client.c tcp_net_socket.c
//运行程序
./tcp_net_server 172.16.125.150 8888
./tcp_net_client 172.16.125.150 8888


此处的ip最好填写本机IP,端口号填写大于1024的整数就好。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: