超详细c语言tcp通信接口
- 1、可下载源码(客户端 || 服务端通信)
- 2、说明
- 3、接口代码
- 4、客户端通信main_client_demo.c
- 5、服务端通信main_server_demo.c
1、可下载源码(客户端 || 服务端通信)
tcp通信代码资源
2、说明
功能:tcp服务端与多个客户端进行通信(服务端通过多线程方式处理客户端服务),初始设置参数,解决服务端重启出现地址占用问题
编译:
make clean
make
执行:
(tcp服务端,系统中只能运行一个)
./server
(tcp客户端,可运行多个,打开另外的终端窗口执行)
./client
3、接口代码
.h头文件
#ifndef _TCP_CLIENT_AND_SERVER_H_
#define _TCP_CLIENT_AND_SERVER_H_
int tcp_creat_socket(void);
int tcp_client_connect(int sockfd, char *server_ip, int server_port);
int tcp_send(int sockfd, void *sendBuf, int len);
int tcp_blocking_rcv(int sockfd, void *recvBuf, int len);
int tcp_noblocking_rcv(int sockfd, void *recvBuf, int len, int timeval_sec, int timeval_usec);
void tcp_close(int sockfd);
int tcp_server_bind_and_listen(int sockfd, char *server_ip, int server_port, int max_listen_num);
int tcp_server_wait_connect(int sockfd);
void tcp_server_creat_pthread_process_client(int *new_sockfd, void* (*callBackFun)(void*));
void *tcp_server_callBackFun_demo(void *ptr);
#endif
.c源码
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <arpa/inet.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netinet/ip.h>
#include <pthread.h>
#include <stdbool.h>
int tcp_creat_socket(void)
{
int sockfd = 0;
sockfd = socket(AF_INET, SOCK_STREAM, 0);
if (0 > sockfd) {
perror("socket");
return -1;
}
int bReuseaddr = 1;
if(0 > setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, (const char*)&bReuseaddr, sizeof(int))) {
perror("setsockopt");
}
#if 0
int bDontLinger = 0;
if(0 > setsockopt(sockfd, SOL_SOCKET, SO_LINGER, (const char*)&bDontLinger, sizeof(int))) {
perror("setsockopt");
}
#endif
#if 0
int nRecvBuf = 32*1024;
setsockopt(sockfd, SOL_SOCKET, SO_RCVBUF, (const char*)&nRecvBuf, sizeof(int));
int nSendBuf = 32*1024;
setsockopt(sockfd, SOL_SOCKET, SO_SNDBUF, (const char*)&nSendBuf, sizeof(int));
#endif
return sockfd;
}
int tcp_client_connect(int sockfd, char *server_ip, int server_port)
{
unsigned int server_addr = 0;
struct sockaddr_in st_server_addr = {0};
st_server_addr.sin_family = AF_INET;
st_server_addr.sin_port = htons(server_port);
inet_pton(AF_INET, server_ip, &server_addr);
st_server_addr.sin_addr.s_addr = server_addr;
if (0 > connect(sockfd, (struct sockaddr *)&st_server_addr, sizeof(st_server_addr))) {
perror("connect");
return -1;
}
return 0;
}
int tcp_send(int sockfd, void *sendBuf, int len)
{
int sendbytes = 0;
if (0 > (sendbytes = send(sockfd, sendBuf, len, MSG_DONTWAIT|MSG_NOSIGNAL))) {
perror("send");
return -1;
}
return sendbytes;
}
int tcp_blocking_rcv(int sockfd, void *recvBuf, int len)
{
int recvbytes = 0;
if (0 > (recvbytes = recv(sockfd, recvBuf, len, 0)) ) {
perror("recv");
return -1;
}
return recvbytes;
}
int tcp_noblocking_rcv(int sockfd, void *recvBuf, int len, int timeval_sec, int timeval_usec)
{
fd_set readset;
struct timeval timeout={0, 0};
int maxfd = 0;
int recvbytes = 0;
int ret = 0;
timeout.tv_sec = timeval_sec;
timeout.tv_usec = timeval_usec;
FD_ZERO(&readset);
FD_SET(sockfd, &readset);
maxfd = sockfd + 1;
ret = select(maxfd, &readset, NULL, NULL, &timeout);
if (0 > ret) {
return -2;
} else {
if (FD_ISSET(sockfd, &readset)) {
if (0 > (recvbytes = recv(sockfd, recvBuf, len, MSG_DONTWAIT))) {
perror("recv");
return -1;
}
} else {
return -1;
}
}
return recvbytes;
}
void tcp_close(int sockfd)
{
if (sockfd > 0) {
close(sockfd);
}
}
int tcp_server_bind_and_listen(int sockfd, char *server_ip, int server_port, int max_listen_num)
{
unsigned int server_addr = 0;
struct sockaddr_in st_LocalAddr = {0};
st_LocalAddr.sin_family = AF_INET;
st_LocalAddr.sin_port = htons(server_port);
inet_pton(AF_INET, server_ip, &server_addr);
st_LocalAddr.sin_addr.s_addr = server_addr;
if(0 > bind(sockfd, (struct sockaddr *)&st_LocalAddr, sizeof(st_LocalAddr))) {
perror("bind");
return -1;
}
if(0 > listen(sockfd, max_listen_num)) {
perror("listen");
return -1;
}
return 0;
}
int tcp_server_wait_connect(int sockfd)
{
int new_sockfd = 0;
struct sockaddr_in st_RemoteAddr = {0};
socklen_t socklen = 0;
new_sockfd = accept(sockfd, (struct sockaddr *)&st_RemoteAddr, &socklen);
if(0 > new_sockfd) {
perror("accept");
return -1;
}
return new_sockfd;
}
void tcp_server_creat_pthread_process_client(int *new_sockfd, void* (*callBackFun)(void*))
{
pthread_t thread_id;
int ret = 0;
pthread_create(&thread_id, NULL, callBackFun, (void *)new_sockfd);
pthread_detach(thread_id);
}
void *tcp_server_callBackFun_demo(void *ptr)
{
int new_sockfd = *(int *)ptr;
printf("新建线程处理客户端服务(new_sockfd=%d)\n", new_sockfd);
char recv_buff[1024] = {0};
int recv_len = 0;
char *str = NULL;
while (1) {
memset(recv_buff, 0, sizeof(recv_buff));
recv_len = tcp_blocking_rcv(new_sockfd, recv_buff, sizeof(recv_buff));
if(0 > recv_len) {
printf("接收客户端消息失败(new_sockfd=%d)!\n", new_sockfd);
break;
} else if(0 == recv_len) {
printf("客户端断开连接(new_sockfd=%d)\n", new_sockfd);
break;
} else {
printf("接收客户端消息(new_sockfd=%d):%s\n", new_sockfd, recv_buff);
str = (char *)"服务端已收到";
tcp_send(new_sockfd, str, strlen(str));
}
}
tcp_close(new_sockfd);
printf("退出线程服务(new_sockfd=%d)\n", new_sockfd);
return NULL;
}
4、客户端通信main_client_demo.c
#include<stdio.h>
#include<string.h>
#include<unistd.h>
#include<pthread.h>
#include"tcp_spi.h"
int sockfd = -1;
int tcp_client_connectflag = 0;
void *fun_client_rcv(void *ptr)
{
char recvBuf[1024] = {0};
int recvBytes = 0;
while (1) {
if (1 == tcp_client_connectflag) {
memset(recvBuf, 0, sizeof(recvBuf));
recvBytes = tcp_blocking_rcv(sockfd, recvBuf, sizeof(recvBuf));
if (0 > recvBytes) {
printf("接收失败\n");
tcp_client_connectflag = 0;
} else if (0 == recvBytes) {
printf("已断开连接\n");
tcp_client_connectflag = 0;
} else {
printf("接收到消息:%s\n", recvBuf);
}
} else {
sleep(1);
}
}
return NULL;
}
void *fun_client_send(void *ptr)
{
char msg_buf[1024] = {0};
while (1) {
if (1 == tcp_client_connectflag) {
printf("\n请输入要发送的消息:\n");
scanf("%s", msg_buf);
printf("正在发送\n");
if (0 > tcp_send(sockfd, msg_buf, strlen(msg_buf))) {
printf("发送失败...!\n");
tcp_client_connectflag = 0;
} else {
printf("发送成功\n");
}
sleep(1);
} else {
sleep(1);
}
}
return NULL;
}
int main(int argc, char *argv[])
{
char server_ip[16] = {0};
int server_port = 0;
int ret = 0;
pthread_t thread_client_rcv, thread_client_send;
ret = pthread_create(&thread_client_rcv, NULL, fun_client_rcv, NULL);
if (ret < 0) {
printf("creat thread_client_rcv is fail!\n");
return -1;
}
ret = pthread_create(&thread_client_send, NULL, fun_client_send, NULL);
if (ret < 0) {
printf("creat fun_client_send is fail!\n");
return -1;
}
printf("请输入服务器ip:\n");
scanf("%s", server_ip);
printf("请输入服务器端口:\n");
scanf("%d", &server_port);
while (1) {
if (0 == tcp_client_connectflag) {
if (sockfd > 0) {
tcp_close(sockfd);
}
sockfd = tcp_creat_socket();
if (0 > sockfd) {
printf("socket创建失败...!\n");
sleep(2);
continue;
}
printf("请求连接...\n");
if (0 > tcp_client_connect(sockfd, server_ip, server_port)) {
printf("连接失败...重连中...\n");
sleep(2);
continue;
} else {
tcp_client_connectflag = 1;
printf("连接成功!\n");
}
} else {
sleep(1);
}
}
tcp_close(sockfd);
pthread_join(thread_client_rcv, NULL);
pthread_join(thread_client_send, NULL);
return 0;
}
5、服务端通信main_server_demo.c
#include<stdio.h>
#include<string.h>
#include<unistd.h>
#include<pthread.h>
#include"tcp_spi.h"
void *tcp_server_callBackFun(void *ptr)
{
int new_sockfd = *(int *)ptr;
printf("开启线程服务处理客户端(new_sockfd=%d)\n", new_sockfd);
char recv_buff[1024] = {0};
int recv_len = 0;
char *str = NULL;
while (1) {
memset(recv_buff, 0, sizeof(recv_buff));
recv_len = tcp_blocking_rcv(new_sockfd, recv_buff, sizeof(recv_buff));
if(0 > recv_len) {
printf("接收客户端消息失败(new_sockfd=%d)!\n", new_sockfd);
break;
} else if(0 == recv_len) {
printf("客户端断开连接(new_sockfd=%d)\n", new_sockfd);
break;
} else {
printf("收到客户端消息(new_sockfd=%d):%s\n", new_sockfd, recv_buff);
str = (char *)"服务端已收到";
tcp_send(new_sockfd, str, strlen(str));
}
}
tcp_close(new_sockfd);
printf("退出线程服务(new_sockfd=%d)\n", new_sockfd);
return NULL;
}
int main(int argc, char *argv[])
{
int ret = 0;
int sockfd = -1;
sockfd = tcp_creat_socket();
if (0 > sockfd) {
printf("socket创建失败...!\n");
return -1;
}
int port = 2022;
char *ip = (char *)"127.0.0.1";
ret = tcp_server_bind_and_listen(sockfd, ip, port, 1024);
if (0 > ret) {
printf("bind_and_listen失败...!\n");
tcp_close(sockfd);
return -1;
}
printf("服务端ip=localHost, 端口=%d\n", port);
int new_sockfd = -1;
while (1) {
if (0 > (new_sockfd = tcp_server_wait_connect(sockfd))) {
printf("等待连接失败...!\n");
continue;
} else {
printf("\n有客户端连接成功! new_sockfd=%d\n", new_sockfd);
tcp_server_creat_pthread_process_client(&new_sockfd, tcp_server_callBackFun);
}
}
tcp_close(sockfd);
return 0;
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)