Linux TCP通信示例

TCP通信流程

server.h

#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <strings.h>
#include <ctype.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#define MAX_LINE 100
/*  用于将大写字符转换为小写字符。参数为需要转换的字符串 */
void my_fun(char * p)
{
	if(p == NULL)				 /* 空串 */
		return;
	for (; *p != '\0'; p++)
		if(*p >= 'A' && *p <= 'Z') /* 判断字符并进行转换,也可以使用库函数 */
			*p = *p -'A' + 'a';
}
int main(void)
{
	struct sockaddr_in sin;
	struct sockaddr_in cin;
	int l_fd;
	int c_fd;
	socklen_t len;
	char buf[MAX_LINE];					/* 存储传送内容的缓冲区 */
	char addr_p[INET_ADDRSTRLEN];		/* 存储客户端地址的缓冲区 */
	int port = 8000;					/* 端口号,使用8000 */
	int n;								/* 读写字节数 */
	bzero(&sin, sizeof(sin));			/* 清空地址结构 */
	sin.sin_family = AF_INET;			/* 使用IPv4通信域 */
	sin.sin_addr.s_addr = INADDR_ANY;	/* 服务器可以接受任意地址 */
	sin.sin_port = htons(port);		/* 端口号转换为网络字节序 */
	l_fd = socket(AF_INET, SOCK_STREAM, 0); /* 创立套接字,使用TCP协议 */
	bind(l_fd, (struct sockaddr*) &sin, sizeof(sin)); /* 将地址和套接字绑定 */
	listen(l_fd, 10);						/* 开始监听连接请求 */
	printf("waiting ...\n");
	while(1){       /* 服务器程序多半是死循环 */
		            /* 接受连接请求,从此函数中返回后就可以开始通信了 */
		c_fd = accept(l_fd, (struct sockaddr*) &cin, &len); 
		n = read(c_fd, buf, MAX_LINE);	        /* 读取客户端传来的信息 */
		inet_ntop(AF_INET, &cin.sin_addr, addr_p, sizeof(addr_p));
											/* 将客户端地址转换为字符串 */
		printf("client IP is %s, port is %d\n", addr_p, ntohs(cin.sin_port)); 											/* 打印客户端地址和端口号 */
		printf("content is : %s\n", buf);	/* 打印客户端发送过来的字符串 */
		my_fun(buf);
		write(c_fd, buf, n);				/* 将转换后的字串发给客户端 */
		close(c_fd);			/* 通信结束,关闭套接字,准备下一次通信 */
	}
	if(close(l_fd) == -1){		/* 通信结束,关闭套接字,准备下一次通信 */
		perror("fail to close");
		exit(1);
	}
	return 0; 
}

client.c

#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <strings.h>
#include <string.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#define MAX_LINE 100
int main(int argc, char *argv[])
{
	struct sockaddr_in sin;	/* 服务器的地址 */
	char buf[MAX_LINE];
	int sfd;
	int port = 8000;
	char *str = "test sting";	/* 默认的字符串 */
	if (argc > 1) {
		str = argv[1];			/* 从命令行参数中取得用户输入的串 */
	}
	bzero(&sin, sizeof(sin));
	sin.sin_family = AF_INET;	/* 使用IPv4地址族 */
	/* 和本机通信,同一台主机担任服务器和客户端的角色 */
	inet_pton(AF_INET, "127.0.0.1", &sin.sin_addr); 
	sin.sin_port = htons(port);        /* 端口号使用8000,必须和服务器端的一致才行 */
	sfd = socket(AF_INET, SOCK_STREAM, 0);	/* 创建套接字 */
	connect(sfd, (const struct sockaddr *)&sin, sizeof(sin));
										/* 主动连接服务器 */
	write(sfd, str, strlen(str) + 1); /* 发送字符串,该串包含‘\0’结束符 */
	/* 读取服务器程序发回的串,由于是同一台主机通信,不存在延时的问题。
	* 但是在真正的网络环境中,要处理读操作的延时问题。
	*/
	read(sfd, buf, MAX_LINE); 
	printf("recive from server: %s\n", buf); /* 打印该串 */
	close(sfd);								   /* 关闭套接字,结束通信 */
	return 0;
}

makefile

all:server client

server:server.c
        gcc server.c -o server 
client:client.c
        gcc client.c -o client

clean:
        rm *.o server client

.PHONY:clean

测试

 

关于程序中用到的函数可直接在终端中使用命令:man 函数名

比如查找socket函数用法信息:man socket

 

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值