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

环境:服务器端用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连接步骤。

此外,写那么多文件是为了日后扩展,毕竟已经上班了,再不能没有规范的乱写代码了。谢谢。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值