基於TCP的socket編程

、 預備知識
1 、socket
1 是網絡編程的一個編程接口,是一個特殊的文件描述符
並不僅限於tcp/ip,也可用於本機通訊
2 流式套接字TCP ,數據報套接字 UDP,原始套接字可直接操作網絡層發送數據
3 套接口位於應用層和傳輸層直接
2、 IP地址
192.168.1.123 ->可以轉換爲32爲無符號正數,每一組數字代表一個字節
分爲 A B C D四類,D類爲組播地址
子網掩碼 255.255.255.0
192.168.1.123 & 255.255.255.0 = 192.168.1.0 網絡地址
inet_addr() 192.168.1.123 轉換成32位無符號正數
inet_ntoa() 32位無符號正數轉換成192.168.1.123
3 、端口號
通過協議和端口號可以確定傳輸層的數據交給那個進程處理
TCP端口號和UDP端口號獨立
4、 網絡字節序
網絡字節序 大端
大端存儲數據低字節存高位,高字節存低位數據
小端存儲數據低字節存低位。高字節存高位
字節序轉換函數,h:host, n:net, l:u_long, s:u_short
htonl ,htons, ntohl, ntohs
二、 系統調用
1 、socket
int socket (int domain, int type, int protocol);
domain:地址族 AF_INET ipv4
type:指定套接口類型
protocol:通常設置爲0
返回值:socket描述符
2 、int bind(int sockfd, struct sockaddr *my_addr, int addrlen) ;
將socket綁定端口和地址,sockaddr是一個通用地址結構
注意sa_data字符數組用來保存地址和端口數據
struct sockaddr
{
u_short sa_family; // 地址族, AF_xxx
char sa_data[14]; // 14字節協議地址
};
通常使用sockaddr_in來設置地址和端口,然後轉換成sockadd類型指針使用
struct sockaddr_in struct sockaddr_un
{
u_short sin_family; // 地址族, AF_INET,2 bytes
u_short sin_port; // 端口,2 bytes
struct in_addr sin_addr; // IPV4地址,4 bytes
char sin_zero[8]; // 8 bytes unused,作爲填充
};
3 、int listen (int sockfd, int backlog)
指定正在等待隊列的長度
4、 int accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen) ;
接受一個客戶端連接,返回值爲已經建立好的socket描述符
sockfd:監聽套接字
addr:accept後又accept填充此結構體,可以通過sockaddr_in獲取對方IP和端口
addrlen:sockaddr長度
5、 int connect(int sockfd, struct sockaddr *serv_addr, int addrlen);
sockfd: 客戶端socket
serv_addr: 服務端接口和地址
addrlen :sockaddr結構體長度
6 、ssize_t send(int socket, const void *buffer, size_t length, int flags)
socket:發送數據的socket
buffer:發送數據buf
length:發送數據長度
flags:通常爲0
7 、ssize_t recv(int socket, const void *buffer, size_t length, int flags)
socket:接受數據的socket
buffer:保存數據buf
lenght:保存數據的buf大小
flags:通常爲0

server.c

#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>          /* See NOTES */
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>

#define BUF_SIZE 100

int main()
{
	//create socket
	int iServer = socket(AF_INET, SOCK_STREAM, 0);
	if (-1 == iServer)
	{
		return -1;
	}
	printf("create socket ok\r\n");
	//bind
	struct sockaddr_in stServer;
	memset(&stServer, 0, sizeof(struct sockaddr_in));
	stServer.sin_family  = AF_INET;
	stServer.sin_port = htons(8888);
	//stServer.sin_addr.s_addr = inet_addr("0.0.0.0");
	stServer.sin_addr.s_addr = INADDR_ANY;
	int iRet = bind(iServer, (struct sockaddr *)&stServer, sizeof(struct sockaddr_in));
	if (-1 == iRet)
	{
		return -1;
	}	
	printf("bind ok\r\n");
	//listen
	iRet = listen(iServer, 5);
	if (-1 == iRet)
	{
		return -1;
	}
	printf("listen ok\r\n");
	//accept
	struct sockaddr_in stClient;
	socklen_t tLen = sizeof(struct sockaddr_in);
	char buf[BUF_SIZE];
	while(1)
	{
		memset(&stClient, 0, sizeof(struct sockaddr_in));
		memset(buf, 0, BUF_SIZE);
		int iClient = accept(iServer, (struct sockaddr *)&stClient, &tLen);
		if (iClient < 0)
		{
			continue;
		}
		printf("accept ok %d\r\n", iClient);
		//recv send
		iRet = recv(iClient, buf, BUF_SIZE, 0);
		printf("recv %d\r\n", iRet);
		if (iRet > 0)
		{
			printf("%s\r\n", buf);
			send(iClient, buf, BUF_SIZE, 0);
		}
		close(iClient);
	}
	//close
	close(iServer);
	return 0;	
}


client.c

#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>          /* See NOTES */
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>

#define BUF_SIZE 100

int main()
{
	//create socket
	int iClient = socket(AF_INET, SOCK_STREAM, 0);
	if (-1 == iClient)
	{
		return -1;
	}
	printf("socket ok\r\n");
	//connect
	struct sockaddr_in stServer;
	memset(&stServer, 0, sizeof(struct sockaddr_in));
	stServer.sin_family = AF_INET;
	stServer.sin_port = htons(8888);
	stServer.sin_addr.s_addr = inet_addr("127.0.0.1");
	int iRet = connect(iClient, (struct sockaddr *)&stServer, sizeof(struct sockaddr));
	if (-1 == iRet)
	{
		perror("connect");
		return -1;
	}
	printf("connect ok\r\n");
	//send
	char buf[BUF_SIZE] = {0};
	strcpy(buf, "hehexixi");
	send(iClient, buf, BUF_SIZE, 0);
	memset(buf, 0, BUF_SIZE);
	//recv
	iRet = recv(iClient, buf, BUF_SIZE, 0);
	printf("%d %s\r\n", iRet, buf);
	return 0;
}



發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章