重温网络编程——协议(二)
前言
在网络传输中有两种特别出名,一种是tcp,一种是udp。
他们都是基于套接字,tcp 属于sock_stream 类型,udp 属于sock_dgram。
sock_steam:
- 传输过程不会有数据丢失。
- 按序传输数据。
- 传输的数据不存在数据边界。
sock_dgram
- 强调快速传输而非传输顺序。
- 传输的数据有数据边界。
- 传输的数据可能会损坏。
4 限制了每次传输数据的大小。
具体可以参考tcp和udp。
关于数据边界:
https://blog.csdn.net/boiled_water123/article/details/81951373
正文
形成一个 socket 需要3个参数(int domain,int type,int protocal):
第一个参数是协议族,为什么有个协议族呢?协议族有ip4和ip6等。
就是一个分类,ip6是完全不兼容ip4的,基于ip6的协议也无法与ip4通讯的。
type 代表性的为:sock_steam,sock_dgram
而sock_steam默认的为tcp,sock_dgram 默认的为udp,所以第三位往往传输为0。
tcp code
服务器端:
#include <stdio.h>
#include <stdlib.h>
#include <WinSock2.h>
#pragma comment(lib, "ws2_32.lib")
void ErrorHandling(char *message);
int main(int argc, char * argv[])
{
WSADATA wsaData;
SOCKET hServerSock, hClientSock;
SOCKADDR_IN serverAddr, clientAddr;
int szclientAddr;
char message[] = "Hello World";
if (argc != 2)
{
printf("Usage :%<port>\n",argv[0]);
exit(1);
}
if (WSAStartup(MAKEWORD(2,2),&wsaData)!=0)
{
ErrorHandling("WASAtartup() error!");
}
hServerSock = socket(PF_INET,SOCK_STREAM,0);
if (hServerSock==INVALID_SOCKET)
{
ErrorHandling("socket() error");
}
memset(&serverAddr,0,sizeof(serverAddr));
serverAddr.sin_family = AF_INET;
serverAddr.sin_addr.s_addr = htonl(INADDR_ANY);
serverAddr.sin_port = htons(atoi(argv[1]));
if (bind(hServerSock,(SOCKADDR *) &serverAddr,sizeof(serverAddr))==SOCKET_ERROR)
{
ErrorHandling("bind() error");
}
if (listen(hServerSock,5)==SOCKET_ERROR)
{
ErrorHandling("listen() Error");
}
szclientAddr = sizeof(clientAddr);
hClientSock = accept(hServerSock,(SOCKADDR *) &serverAddr,&szclientAddr);
if (hClientSock ==INVALID_SOCKET)
{
ErrorHandling("accept error");
}
send(hClientSock,message,sizeof(message),0);
closesocket(hClientSock);
closesocket(hServerSock);
WSACleanup();
return 0;
}
void ErrorHandling(char *message)
{
fputs(message,stderr);
fputs('\n',stderr);
exit(1);
}
client 端:
#include <stdio.h>
#include <stdlib.h>
#include <winsock2.h>
void ErrorHandling(char* message);
int main(int argc,char* argv[]) {
WSADATA wsaData;
SOCKET hSocket;
SOCKADDR_IN servAddr;
char message[30];
int strLen, read_len=0,index=0;
if (argc!=3)
{
printf("Usage : %s <IP> <port>\n",argv[0]);
exit(1);
}
if (WSAStartup(MAKEWORD(2,2),&wsaData)!=0)
{
ErrorHandling("WSAStartup() error!");
}
hSocket = socket(PF_INET,SOCK_STREAM,0);
if (hSocket==INVALID_SOCKET)
{
ErrorHandling("socket() error");
}
memset(&servAddr,0,sizeof(servAddr));
servAddr.sin_family = AF_INET;
servAddr.sin_addr.s_addr = inet_addr(argv[1]);
servAddr.sin_port = htons(atoi(argv[2]));
if (connect(hSocket,(SOCKADDR*) &servAddr,sizeof(servAddr))==SOCKET_ERROR)
{
ErrorHandling("connect() error!");
}
while (read_len=read(hSocket, &message[index++],1))
{
if (read_len==-1)
{
break;
}
strLen += read_len;
}
printf("Message from server:%s \n",message);
closesocket(hSocket);
WSACleanup();
return 0;
}
void ErrorHandling(char* message) {
fputs(message,stderr);
fputc('\n',stderr);
exit(1);
}