《TCP/IP网络编程》第2章

yxqq378287007 2022-01-15 02:48:46 阅读数:813

编程 网络 TCP ip

#include <sys/socket.h>
//成功文件描述符,失败-1
int socket(int domain, int type, int protocol);

协议族(Protocal Family)

PF_INET,IPv4
PF_INET6,IPv6
PF_LOCAL,本地UNIX
PF_PACKET,底层套接字
PF_IPX,IPX Novell

套接字类型(Type)

套接字的数据传输方式。

  • SOCK_STREAM,面向连接
    数据不会消失,可靠;
    按序传输,有序;
    无数据边界(Boundary),基于字节,read()和write()并不一定一致(内部缓冲);
    套接字一一对应。
int tcp_socket = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP);
  • SOCK_DGRAM,面向消息
    数据可能丢失或损毁,不可靠;
    快速而非有序传输,无序高速;
    有数据边界,read()和write()一致(一次传输一次接收);
    限制每次传输数据大小;
int udp_socket = socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP);

TCP客户端

tcp_client.c

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <arpa/inet.h>
#include <sys/socket.h>
void error_handling(char *message);
int main(int argc, char *argv[]) {

int sock;
struct sockaddr_in addr;
socklen_t addr_size;
char message[30];
int str_len=0;
int idx=0;
int read_len=0;
if(argc!=3) {

printf("Usage : %s <IP> <port>\n", argv[0]);
exit(1);
}
sock = socket(PF_INET, SOCK_STREAM, 0);
if(sock==-1)
error_handling("socket() error");
addr_size = sizeof(addr);
memset(&addr, 0, addr_size);
addr.sin_family = AF_INET;
addr.sin_addr.s_addr = inet_addr(argv[1]);
addr.sin_port = htons(atoi(argv[2]));
if(connect(sock, (struct sockaddr*)&addr, addr_size)==-1)
error_handling("connect() error");
while(read_len = read(sock, &message[idx++], 1)) {

if(read_len==-1)
error_handling("read() error");
str_len += read_len;
}
message[str_len] = '\0';
printf("Message from server: %s \n", message);
printf("Function read call count: %d \n", str_len);
close(sock);
return 0;
}
void error_handling(char *message) {

fputs(message, stderr);
fputc('\n', stderr);
exit(1);
}

编译运行

gcc hello_server.c -o hserver
./hserver 9190
gcc tcp_client.c -o hclient
./hclient 127.0.0.1 9190

Windows平台

#include <winsock2.h>
//成功返回套接字句柄,失败INVALID_SOCKET
SOCKET socket(int af, int type, int protocol);

客户端

tcp_client_win.c

#include <stdio.h>
#include <stdlib.h>
#include <winsock2.h>
void ErrorHanding(char *message);
int main(int argc, char *argv[]) {

WSADATA wsaData;
SOCKET hSock;
SOCKADDR_IN servAddr;
char message[30];
int strLen=0;
int idx=0;
int readLen=0;
if(argc!=3) {

printf("Usage : %s <IP> <port>\n", argv[0]);
exit(1);
}
if(WSAStartup(MAKEWORD(2, 2), &wsaData)!=0)
ErrorHanding("WSAStartup() error!");
hSock = socket(PF_INET, SOCK_STREAM, 0);
if(hSock==INVALID_SOCKET)
ErrorHanding("socket() error");
memset(&servAddr, 0, sizeof(SOCKADDR_IN));
servAddr.sin_family = AF_INET;
servAddr.sin_addr.s_addr = inet_addr(argv[1]);
servAddr.sin_port = htons(atoi(argv[2]));
if(connect(hSock, (SOCKADDR *)&servAddr, sizeof(SOCKADDR_IN))==SOCKET_ERROR)
ErrorHanding("connect() error");
while(readLen = recv(hSock, &message[idx++], 1, 0)) {

if(strLen ==-1)
ErrorHanding("read() error");
strLen += readLen;
if(message[idx-1]=='\0')
break;
}
message[strLen] = '\0';
printf("Message from server: %s \n", message);
printf("Function read call count: %d \n", strLen);
closesocket(hSock);
WSACleanup();
return 0;
}
void ErrorHanding(char *message) {

fputs(message, stderr);
fputc('\n', stderr);
exit(1);
}

编译运行

cl /EHsc hello_server_win.c /Fe:hServerWin.exe /link ws2_32.lib
hServerWin 9190
cl /EHsc tcp_client_win.c /Fe:hTCPClientWin.exe /link ws2_32.lib
hTCPClientWin 127.0.0.1 9190
版权声明:本文为[yxqq378287007]所创,转载请带上原文链接,感谢。 https://blog.csdn.net/oqqyx1234567/article/details/122318741