关于TCP,UDP这块其实就是下面这几个步骤:(左边的是服务器的,右边是客户端的)务必注意两者的区别!!
TCP:
utili.h
#include<stdio.h>
#include<unistd.h>
#include<sys/socket.h>
#include<string.h>
#include<stdlib.h>
#include<netinet/in.h>
#include<arpa/inet.h>
#define SERVER_PORT 8080
#define SERVER_IP "127.0.0.1"
#define LISTEN_QUEUE_SIZE 5
#define BUFFER_SIZE 256
ser.c
#include"utili.h"
int main()
{
int sockSer = socket(AF_INET, SOCK_STREAM, 0);
if(sockSer == -1)
{
perror("socket");
exit(1);
}
struct sockaddr_in addrSer, addrCli;
addrSer.sin_family = AF_INET;
addrSer.sin_port = htons(SERVER_PORT); //这里的port和IP参数其实最好用main函数
的参数传更好,可以参考下文中UDP的ser.c
addrSer.sin_addr.s_addr = inet_addr(SERVER_IP);
socklen_t len = sizeof(struct sockaddr);
int ret = bind(sockSer, (struct sockaddr*)&addrSer, len);
if(ret == -1)
{
perror("bind");
exit(1);
}
ret = listen(sockSer, LISTEN_QUEUE_SIZE);
if(ret == -1)
{
perror("listen");
exit(1);
}
int sockConn = accept(sockSer, (struct sockaddr*)&addrCli, &len);
if(sockConn == -1)
{
printf("Server Accept Client Connect Fail.\n");
exit(1);
}
else
{
printf("Server Accept Client Connect Success.\n");
}
char sendbuf[BUFFER_SIZE];
char recvbuf[BUFFER_SIZE];
while(1)
{
printf("Ser:>");
scanf("%s", sendbuf);
send(sockConn, sendbuf, strlen(sendbuf)+1, 0);
recv(sockConn, recvbuf, BUFFER_SIZE, 0);
printf("Cli:>%s\n", recvbuf);
}
close(sockSer);
return 0;
}
cli.c
#include"utili.h"
int main()
{
int sockCli = socket(AF_INET, SOCK_STREAM, 0);
if(sockCli == -1)
{
perror("socket");
exit(1);
}
struct sockaddr_in addrSer;
addrSer.sin_family = AF_INET;
addrSer.sin_port = htons(SERVER_PORT);
addrSer.sin_addr.s_addr = inet_addr(SERVER_IP);
socklen_t len = sizeof(struct sockaddr);
int ret = connect(sockCli, (struct sockaddr*)&addrSer, len);
if(ret == -1)
{
perror("connect");
exit(1);
}
else
{
printf("Client Connect Server Success.\n");
}
char sendbuf[BUFFER_SIZE];
char recvbuf[BUFFER_SIZE];
while(1)
{
recv(sockCli, recvbuf, BUFFER_SIZE, 0);
printf("Ser:>%s\n",recvbuf);
printf("Cli:>");
scanf("%s", sendbuf);
send(sockCli, sendbuf, strlen(sendbuf)+1, 0);
}
close(sockCli);
return 0;
}
运行效果:(不过这里只能一人一句,而且这个服务器只能给一个客户端服务)
UDP:
ser.c
#include"utili.h"
int main(int argc, char*argv[])
{
if(argc <= 2)
{
printf("usage: %s ip_address port_number\n",basename(argv[0]));
return 1;
}
char *ip = argv[1];
int port = atio(argv[2]);
int sockSer = socket(AF_INET, SOCK_DGRAM, 0);
if(sockSer == -1)
{
perror("socket");
return -1;
}
struct sockaddr_in addrSer, addrCli;
addrSer.sin_family = AF_INET;
addrSer.sin_port = htons(port);
addrSer.sin_addr.s_addr = inet_addr(ip);
socklen_t len = sizeof(struct sockaddr);
int ret = bind(sockSer, (struct sockaddr*)&addrSer, len);
if(ret == -1)
{
perror("bind");
return -1;
}
char sendbuf[BUFFER_SIZE];
char recvbuf[BUFFER_SIZE];
while(1)
{
recvfrom(sockSer, recvbuf, BUFFER_SIZE, 0, (struct sockaddr*)&addrCli, &len);
printf("Cli:>%s\n",recvbuf);
printf("Ser:>");
scanf("%s",sendbuf);
sendto(sockSer, sendbuf, strlen(sendbuf)+1, 0, (struct sockaddr*)&addrCli,len);
}
close(sockSer);
return 0;
}
cli.c
#include"utili.h"
int main()
{
int sockCli = socket(AF_INET, SOCK_DGRAM, 0);
if(sockCli == -1)
{
perror("sockCli");
return -1;
}
struct sockaddr_in addrSer, addrCli;
addrSer.sin_family = AF_INET;
addrSer.sin_port = htons(SERVER_PORT);
addrSer.sin_addr.s_addr = inet_addr(SERVER_IP);
socklen_t len = sizeof(struct sockaddr);
char sendbuf[BUFFER_SIZE];
char recvbuf[BUFFER_SIZE];
while(1)
{
printf("cli:>");
scanf("%s",sendbuf);
sendto(sockCli, sendbuf, strlen(sendbuf)+1, 0, (struct sockaddr*)&addrSer, len);
recvfrom(sockCli, recvbuf, BUFFER_SIZE, 0, (struct sockaddr*)&addrSer, &len);
printf("ser:>%s\n", recvbuf);
}
close(sockCli);
return 0;
}
运行结果:(相较于上面那个用TCP的服务器,这里的这个UDP服务器可以给多个客户端服务,但还是只能一人一句。。。)
其实关于TCP ,UDP应用很广,这里就只是些皮毛,上面的程序其实还有好多弊端。。。所以这就牵扯到关于多线程,多进程,以及IO复用等等一些一系列基于tcp,udp之上的技术。。。