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

Linux 自虐之路(三): 一个简单的TCP通信例子

2016-09-15 19:31 381 查看
环境:服务器端用linux c编写,运行于linux mint18.

           客户端用vs控制台编写,运行于Win 7.

Server端:

main.c文件

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <pthread.h>
#include <netinet/in.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <netdb.h>
#include <unistd.h>  /* for func: close */
#include <ctype.h>

#include "base_type.h"
#include "util_string.h"

#define MAX_BUF_LEN 1000
const INT g_iServerPort = 8000;

extern BOOL str_toUpper(IN CHAR *srcStr,OUT CHAR *dstStr);

int main()
{
struct sockaddr_in stSockIn;
struct sockaddr_in stSockClient;
INT sock_fd = 0;            /* 监听socket */
INT sock_ConFd =0;          /* 连接socket */
INT addr_size = 0;
CHAR RecvBuf[MAX_BUF_LEN]={0};
CHAR SendBuf[MAX_BUF_LEN]={0};

sock_fd = socket(AF_INET,SOCK_STREAM,0);
if ( -1 == sock_fd)
{
perror("Create socket failed.\n");
return -1;
}
memset(&stSockIn,0,sizeof(struct sockaddr_in));
memset(&stSockClient,0,sizeof(struct sockaddr_in));
stSockIn.sin_family = AF_INET;
stSockIn.sin_addr.s_addr = INADDR_ANY;
stSockIn.sin_port = htons(g_iServerPort);

if ( -1 == bind(sock_fd,(struct sockaddr *)&stSockIn,sizeof(stSockIn)) )
{
perror("Bind socket failed.\n");
return 0;
}
if ( -1 == listen(sock_fd,30) )
{
perror("Listen failed.\n");
return 0;
}
printf("---------server is accepting connection.------\n");
while ( 1 )
{
sock_ConFd= accept(sock_fd,(struct sockaddr *)&stSockClient,&addr_size);
if ( -1 == sock_ConFd)
{
perror("accept failed.\n");
break;
}
else
{
/* 获取已连接的client的地址信息 */
printf("The client IP(%s):Port(%d) connected.\n",
inet_ntoa(stSockClient.sin_addr),
ntohs(stSockClient.sin_port));
}
if ( -1 == recv(sock_ConFd,RecvBuf,MAX_BUF_LEN,0) )
{
perror("Server Recv failed.\n");
break;
}
printf("recv data : %s.\n",RecvBuf);

str_toUpper(RecvBuf,SendBuf);
/* send */
if ( -1 == send(sock_ConFd,SendBuf,strlen(SendBuf),0))
{
perror("Server send data failed!\n");
break;
}
close(sock_ConFd);
}
close(sock_fd);
return 0;
}
base_type.h文件

#ifndef BASE_TYPE_H
#define BASE_TYPE_H

#define UCHAR unsigned char
#define CHAR char
#define UINT unsigned int
#define INT int
#define ULONG unsigned long

typedef enum tagBOOL
{
FALSE=0,
TRUE
}BOOL;
#ifndef IN
#define IN
#endif
#ifndef OUT
#define OUT
#endif
#ifndef INOUT
#define INOUT
#endif

#endif
util_string.h

#ifndef UTIL_STRING_H
#define UTIL_STRING_H

BOOL str_toUpper(IN CHAR *srcStr,OUT CHAR *dstStr);
BOOL str_toLower(IN CHAR * srcStr, OUT CHAR * dstStr);

#endif
util_string.c

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>

#include "util_string.h"
#include "base_type.h"

/*****************************************************************************
* 函 数 名  : str_toUpper
* 负 责 人  : zhaogang
* 创建日期  : 2016年9月15日
* 函数功能  : 将str中的小写字符转大写字符
* 输入参数  : IN CHAR * srcStr   源str
OUT CHAR * dstStr  结果str(调用者自己保证内存已分配)
* 输出参数  : 无
* 返 回 值  :
* 调用关系  :
* 其    它  :

*****************************************************************************/
BOOL str_toUpper(IN CHAR * srcStr, OUT CHAR * dstStr)
{
INT iIndex = 0;
if ( (NULL == srcStr) || (NULL == dstStr))
{
printf("Invalid params: p1(%p),p2(%p).",srcStr,dstStr);
return FALSE;
}
INT iSrcLen = strlen(srcStr);
for (iIndex = 0; iIndex <iSrcLen; iIndex++)
{
dstStr[iIndex] = (CHAR)toupper(srcStr[iIndex]);
}
dstStr[iIndex]='\0';
return TRUE;
}

/*****************************************************************************
* 函 数 名  : str_toLower
* 负 责 人  : zhaogang
* 创建日期  : 2016年9月15日
* 函数功能  : 将源字符串所有大写转小写
* 输入参数  : IN CHAR * srcStr   原始字符串
OUT CHAR * dstStr  转换后字符串
* 输出参数  : 无
* 返 回 值  :
* 调用关系  :
* 其    它  :

*****************************************************************************/
BOOL str_toLower(IN CHAR * srcStr, OUT CHAR * dstStr)
{
INT iIndex =0;
INT iSrcLen = 0;
if ( (NULL == srcStr) || (NULL == dstStr))
{
printf("Invalid params: p1(%p),p2(%p).",srcStr,dstStr);
return FALSE;
}
iSrcLen = strlen(srcStr);
for (iIndex = 0; iIndex<srcStr ; iIndex++)
{
dstStr[iIndex] = (CHAR)(tolower(srcStr[iIndex]));
}
dstStr[iIndex]='\0';
return TRUE;
}
client端:(win32 --直接抄的网上的)

#include <WINSOCK2.H>
#include <STDIO.H>

#pragma  comment(lib,"ws2_32.lib")

#define MAX_BUF_LEN 1000

const int g_iServerPort = 8000;
const char g_szServerIP[] = "192.168.16.112";

int main(int argc, char* argv[])
{
WORD sockVersion = MAKEWORD(2, 2);
WSADATA data;
if (WSAStartup(sockVersion, &data) != 0)
{
return 0;
}

SOCKET sclient = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
if (sclient == INVALID_SOCKET)
{
printf("invalid socket !");
return 0;
}

sockaddr_in serAddr;
serAddr.sin_family = AF_INET;
serAddr.sin_port = htons(g_iServerPort);
serAddr.sin_addr.S_un.S_addr = inet_addr(g_szServerIP);
if (connect(sclient, (sockaddr *)&serAddr, sizeof(serAddr)) == SOCKET_ERROR)
{
printf("connect error !");
closesocket(sclient);
return 0;
}
char * sendData = "this is client send data!";
send(sclient, sendData, strlen(sendData), 0);

char recData[MAX_BUF_LEN] = {0};
int ret = recv(sclient, recData, MAX_BUF_LEN, 0);
if (ret > 0)
{
recData[ret] = 0x00;
printf(recData);
}
closesocket(sclient);
WSACleanup();
return 0;
}
测试结果:



说明:

由于我有两台物理机,一台装的win7,一台装的linux mint,因此Client端连接的IP的地址是服务器的IP地址,如果装的虚拟机(双系统),用环回地址127.0.0.1测试。我主要是学习不同操作系统下内核编程,客户端直接copy过来,希望观众查找资料深入理解TCP连接步骤。

此外,写那么多文件是为了日后扩展,毕竟已经上班了,再不能没有规范的乱写代码了。谢谢。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  tcp