Linux 自虐之路(三): 一个简单的TCP通信例子
2016-09-15 19:31
387 查看
环境:服务器端用linux c编写,运行于linux mint18.
客户端用vs控制台编写,运行于Win 7.
Server端:
main.c文件
说明:
由于我有两台物理机,一台装的win7,一台装的linux mint,因此Client端连接的IP的地址是服务器的IP地址,如果装的虚拟机(双系统),用环回地址127.0.0.1测试。我主要是学习不同操作系统下内核编程,客户端直接copy过来,希望观众查找资料深入理解TCP连接步骤。
此外,写那么多文件是为了日后扩展,毕竟已经上班了,再不能没有规范的乱写代码了。谢谢。
客户端用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 #endifutil_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); #endifutil_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通信的例子
- linux两个程序通过共享内存通信的一个简单例子
- linux 服务器/客户端 tcp通信的简单例子
- linux两个程序通过共享内存通信的一个简单例子
- 一个简单的Linux下组播通信的例子
- 一个最简单的Socket通信例子
- 一个简单的tcp filter的例子
- Linux下两个程序进行socket通信的简单例子
- 【socket编程】一个简单的基于TCP的客户/服务端例子(vs2008)
- 由一个简单的客户端间TCP/UDP通信程序引发的关于设计模式的思考
- 一个关于linux socket的简单例子
- Linux下,使用C/C++编写"静态链接库"的一个简单例子
- linux下java程序与C语言程序通过SOCKET通信的简单例子
- 一个超简单的ring3与ring0通信的例子
- 一个关于linux socket的简单例子
- TCP网络通信的简单例子
- linux 一个简单的进程创建例子
- 一个简单的tcp filter的例子
- 一个简单的Linux下Client/Server应答例子
- 一个关于linux socket的简单例子