最简单TCP 服务器和客户端代码
重点理解
服务器代码
#include <errno.h>
#include <netinet/in.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <unistd.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include "tcp_define.h"
static int g_while_sleep_sencod = 2;
TCP_PACKET_DATA_T recv_data;
TCP_PACKET_DATA_T send_data;
int main(int argc, char *argv[])
{
int sock_fd = -1;
int accept_fd = -1;
int ret = 0;
struct sockaddr_in servaddr;
char send_buf[MAX_BUFFER_SZIE] = "This buffer is in Server!!!!";
uint64_t run_cnt = 0;
struct sockaddr_in client;
socklen_t len = sizeof(client);
char *tcp_server_ip = (char *)TCP_SERVER_IP;
uint16_t tcp_server_port = (uint16_t)TCP_SERVER_PORT;
sock_fd = socket(AF_INET, SOCK_STREAM, 0);
if (-1 == sock_fd)
{
printf("create socket error: %s(errno: %d)\n", strerror(errno), errno);
return 0;
}
memset(&servaddr, 0, sizeof(servaddr));
servaddr.sin_family = AF_INET;
servaddr.sin_addr.s_addr = inet_addr(tcp_server_ip);
servaddr.sin_port = htons(tcp_server_port);
// bind是将socket绑定到某个IP和端口
ret = bind(sock_fd, (struct sockaddr *)&servaddr, sizeof(servaddr));
if (-1 == ret)
{
printf("bind socket error: %s(errno: %d)\n", strerror(errno), errno);
goto err_bind_failed;
}
//设置同时与服务器建立连接的(监听)上限数,最大128个
ret = listen(sock_fd, 2);
if (-1 == ret)
{
printf("listen socket error: %s(errno: %d)\n", strerror(errno), errno);
goto err_listen_failed;
}
//这个版本只能用于多个客户端连接,而只有第一个客户端可以发送数据
accept_fd = accept(sock_fd, (struct sockaddr *)&client, &len);
if (-1 == accept_fd)
{
printf("accept socket error: %s(errno: %d)\n", strerror(errno), errno);
goto err_accept_failed;
}
printf("[%s +%d %s] tcp_server_port=%d\n", __FILE__, __LINE__, __func__, tcp_server_port);
printf("[%s +%d %s] tcp_server_ip=%s\n", __FILE__, __LINE__, __func__, tcp_server_ip);
printf("[%s +%d %s] then while recv+send\n", __FILE__, __LINE__, __func__);
run_cnt = 0;
while (1)
{
run_cnt ++;
//阻塞等待第一个客户端的数据的到来,而且是为一个客户端数据的到来。
memset(&recv_data, '\0', sizeof(TCP_PACKET_DATA_T));
ret = recv(accept_fd, &recv_data, sizeof(TCP_PACKET_DATA_T), 0);
printf("[%s +%d %s] recv ret=%d\n", __FILE__, __LINE__, __func__, ret);
if (0 < ret)
{
printf("[%s +%d %s] [%ld] recv from client successful\n", __FILE__, __LINE__, __func__, run_cnt);
printf("[%s +%d %s] recv_data.data=%s, recv_data.size=%d\n", __FILE__, __LINE__, __func__, recv_data.data, recv_data.size);
printf("[%s +%d %s] recv_data.tcp_st=%d, recv_data.run_cnt=%ld\n", __FILE__, __LINE__, __func__, recv_data.tcp_st, recv_data.run_cnt);
}
else if (0 == ret)
{
}
else
{
}
strcpy(send_data.data, send_buf);
send_data.size = strlen(send_data.data);
send_data.tcp_st = TCP_STATUS_HANDSHAKE;
send_data.run_cnt = run_cnt;
ret = send(accept_fd, &send_data, sizeof(TCP_PACKET_DATA_T), 0);
printf("[%s +%d %s] send ret=%d\n", __FILE__, __LINE__, __func__, ret);
if (0 < ret) {
printf("[%s +%d %s] [%ld] send to client successful:\n", __FILE__, __LINE__, __func__, run_cnt);
printf("[%s +%d %s] recv_data.data=%s, recv_data.size=%d\n", __FILE__, __LINE__, __func__, recv_data.data, recv_data.size);
printf("[%s +%d %s] recv_data.tcp_st=%d, recv_data.run_cnt=%ld\n", __FILE__, __LINE__, __func__, recv_data.tcp_st, recv_data.run_cnt);
}
else if (0 == ret) {
}
else {
}
printf("[%s +%d %s] run_cnt=%ld then sleep(%d)\n", __FILE__, __LINE__, __func__, run_cnt, g_while_sleep_sencod);
sleep(g_while_sleep_sencod);
}
err_accept_failed:
err_listen_failed:
err_bind_failed:
if(-1 != sock_fd)
{
close(sock_fd);
sock_fd = -1;
}
return 0;
}
客户端代码
#include <errno.h>
#include <netinet/in.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <unistd.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include "tcp_define.h"
static int g_while_sleep_sencod = 2;
TCP_PACKET_DATA_T recv_data;
TCP_PACKET_DATA_T send_data;
int main(int argc, char *argv[])
{
int sock_fd = -1;
int ret = 0;
struct sockaddr_in servaddr;
char send_buf[MAX_BUFFER_SZIE] = "This buffer is in Client!!!!";
uint64_t run_cnt = 0;
struct sockaddr_in client;
socklen_t len = sizeof(client);
char *tcp_server_ip = (char *)TCP_SERVER_IP;
uint16_t tcp_server_port = (uint16_t)TCP_SERVER_PORT;
pid_t pid = 0;
sock_fd = socket(AF_INET, SOCK_STREAM, 0);
if (-1 == sock_fd)
{
printf("create socket error: %s(errno: %d)\n", strerror(errno), errno);
return 0;
}
pid = getpid();
printf("[%s +%d %s] PID pid=%d\n", __FILE__, __LINE__, __func__, pid);
memset(&servaddr, 0, sizeof(struct sockaddr_in));
servaddr.sin_family = AF_INET;
servaddr.sin_port = htons(tcp_server_port);
servaddr.sin_addr.s_addr = inet_addr(tcp_server_ip);
printf("[%s +%d %s] tcp_server_port=%d\n", __FILE__, __LINE__, __func__, tcp_server_port);
printf("[%s +%d %s] tcp_server_ip=%s\n", __FILE__, __LINE__, __func__, tcp_server_ip);
ret = connect(sock_fd, (struct sockaddr*)&servaddr, len);
while(0 != ret)
{
ret = connect(sock_fd, (struct sockaddr*)&servaddr, len);
if(0 != ret)
{
break;
}
printf("[%s +%d %s] then sleep(1)\n", __FILE__, __LINE__, __func__);
}
printf("[%s +%d %s] then while send+recv\n", __FILE__, __LINE__, __func__);
run_cnt = 0;
while (1)
{
run_cnt ++;
strcpy(send_data.data, send_buf);
send_data.size = strlen(send_data.data);
send_data.tcp_st = TCP_STATUS_HANDSHAKE;
send_data.run_cnt = run_cnt;
ret = send(sock_fd, &send_data, sizeof(TCP_PACKET_DATA_T), 0);
printf("[%s +%d %s] send ret=%d\n", __FILE__, __LINE__, __func__, ret);
if (0 < ret) {
printf("[%s +%d %s] [%ld] sned to client successful:\n", __FILE__, __LINE__, __func__, run_cnt);
printf("[%s +%d %s] recv_data.data=%s, recv_data.size=%d\n", __FILE__, __LINE__, __func__, recv_data.data, recv_data.size);
printf("[%s +%d %s] recv_data.tcp_st=%d, recv_data.run_cnt=%ld\n", __FILE__, __LINE__, __func__, recv_data.tcp_st, recv_data.run_cnt);
}
else if (0 == ret) {
}
else {
}
//阻塞等待第一个客户端的数据的到来,而且是为一个客户端数据的到来。
memset(&recv_data, '\0', sizeof(TCP_PACKET_DATA_T));
ret = recv(sock_fd, &recv_data, sizeof(TCP_PACKET_DATA_T), 0);
printf("[%s +%d %s] recv ret=%d\n", __FILE__, __LINE__, __func__, ret);
if (0 < ret)
{
printf("[%s +%d %s] [%ld] recv from client successful\n", __FILE__, __LINE__, __func__, run_cnt);
printf("[%s +%d %s] recv_data.data=%s, recv_data.size=%d\n", __FILE__, __LINE__, __func__, recv_data.data, recv_data.size);
printf("[%s +%d %s] recv_data.tcp_st=%d, recv_data.run_cnt=%ld\n", __FILE__, __LINE__, __func__, recv_data.tcp_st, recv_data.run_cnt);
}
else if (0 == ret)
{
}
else
{
}
printf("[%s +%d %s] run_cnt=%ld then sleep(%d)\n", __FILE__, __LINE__, __func__, run_cnt, g_while_sleep_sencod);
sleep(g_while_sleep_sencod);
}
if(-1 != sock_fd)
{
close(sock_fd);
sock_fd = -1;
}
return 0;
}
tcp_define.h代码
#ifndef __TCP_DEFINE_H__
#define __TCP_DEFINE_H__
#include <stdint.h>
#define TCP_SERVER_PORT (9999) //tcp服务器端口
#define TCP_SERVER_IP "192.168.70.64" //tcp服务端IP
#define MAX_BUFFER_SZIE (4096) //接收,发送buffer 最大长度
#define MAX_PACKET_DATA_SIZE (128)
typedef enum
{
TCP_STATUS_NONE = 0,
TCP_STATUS_HANDSHAKE,
TCP_STATUS_HANDSHAKE_ACK,
TCP_STATUS_ABNORMAL, // Abnormal
TCP_STATUS_ABNORMAL_ACK,
TCP_STATUS_MAX
} TCP_STATUS_ST;
typedef struct __tcp_packet_data_ {
char data[MAX_PACKET_DATA_SIZE];
uint32_t size;
TCP_STATUS_ST tcp_st;
uint64_t run_cnt;
} TCP_PACKET_DATA_T;
#endif
服务器运行log
[server.c +67 main] tcp_server_port=9999
[server.c +68 main] tcp_server_ip=192.168.70.64
[server.c +70 main] then while recv+send
[server.c +78 main] recv ret=144
[server.c +81 main] [1] recv from client successful
[server.c +82 main] recv_data.data=This buffer is in Client!!!!, recv_data.size=28
[server.c +83 main] recv_data.tcp_st=1, recv_data.run_cnt=1
[server.c +98 main] send ret=144
[server.c +100 main] [1] send to client successful:
[server.c +101 main] recv_data.data=This buffer is in Client!!!!, recv_data.size=28
[server.c +102 main] recv_data.tcp_st=1, recv_data.run_cnt=1
[server.c +108 main] run_cnt=1 then sleep(2)
[server.c +78 main] recv ret=144
[server.c +81 main] [2] recv from client successful
[server.c +82 main] recv_data.data=This buffer is in Client!!!!, recv_data.size=28
[server.c +83 main] recv_data.tcp_st=1, recv_data.run_cnt=2
[server.c +98 main] send ret=144
[server.c +100 main] [2] send to client successful:
[server.c +101 main] recv_data.data=This buffer is in Client!!!!, recv_data.size=28
[server.c +102 main] recv_data.tcp_st=1, recv_data.run_cnt=2
[server.c +108 main] run_cnt=2 then sleep(2)
[server.c +78 main] recv ret=144
[server.c +81 main] [3] recv from client successful
[server.c +82 main] recv_data.data=This buffer is in Client!!!!, recv_data.size=28
[server.c +83 main] recv_data.tcp_st=1, recv_data.run_cnt=3
[server.c +98 main] send ret=144
[server.c +100 main] [3] send to client successful:
客户端运行log
[client.c +40 main] PID pid=3980
[client.c +46 main] tcp_server_port=9999
[client.c +47 main] tcp_server_ip=192.168.70.64
[client.c +59 main] then while send+recv
[client.c +71 main] send ret=144
[client.c +73 main] [1] sned to client successful:
[client.c +74 main] recv_data.data=, recv_data.size=0
[client.c +75 main] recv_data.tcp_st=0, recv_data.run_cnt=0
[client.c +84 main] recv ret=144
[client.c +87 main] [1] recv from client successful
[client.c +88 main] recv_data.data=This buffer is in Server!!!!, recv_data.size=28
[client.c +89 main] recv_data.tcp_st=1, recv_data.run_cnt=1
[client.c +98 main] run_cnt=1 then sleep(2)
[client.c +71 main] send ret=144
[client.c +73 main] [2] sned to client successful:
[client.c +74 main] recv_data.data=This buffer is in Server!!!!, recv_data.size=28
[client.c +75 main] recv_data.tcp_st=1, recv_data.run_cnt=1
[client.c +84 main] recv ret=144
[client.c +87 main] [2] recv from client successful
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。