新聞中心
Socket編程是一種在計(jì)算機(jī)網(wǎng)絡(luò)中進(jìn)行通信的基礎(chǔ)方式,它被廣泛運(yùn)用于網(wǎng)絡(luò)應(yīng)用程序的設(shè)計(jì)中。在Linux環(huán)境中,Socket編程是一種基本的網(wǎng)絡(luò)編程方式,可以實(shí)現(xiàn)客戶端與服務(wù)器之間的數(shù)據(jù)傳輸與通信。在本文中,我們將介紹Linux下的Socket編程,并分享一些簡單的實(shí)例供讀者參考。

一、Socket編程基礎(chǔ)知識(shí)
1.1 Socket定義
Socket是一種通信方式,它是一種計(jì)算機(jī)網(wǎng)絡(luò)數(shù)據(jù)傳輸協(xié)議的API。Socket是一組用于接收和發(fā)送數(shù)據(jù)的API,它可以在計(jì)算機(jī)網(wǎng)絡(luò)上建立連接,進(jìn)行網(wǎng)絡(luò)通信。Socket是一種抽象層,它實(shí)際上是一個(gè)文件描述符,可以用于數(shù)據(jù)的輸入和輸出。
1.2 Socket類型
在Socket編程中,有兩種主要的Socket類型:
– 流Socket(SOCK_STREAM):用于建立面向連接的TCP連接,數(shù)據(jù)傳輸具有可靠性和順序性;
– 數(shù)據(jù)報(bào)Socket(SOCK_DGRAM):用于無連接的UDP通信,數(shù)據(jù)傳輸速度快但不可靠,消息之間沒有順序。
1.3 Socket編程基本流程
在使用Socket編程進(jìn)行數(shù)據(jù)通信時(shí),需要進(jìn)行如下的基本流程:
– 服務(wù)器端創(chuàng)建Socket、綁定IP與端口、監(jiān)聽客戶端連接;
– 客戶端創(chuàng)建Socket、連接服務(wù)器;
– 服務(wù)器端接受客戶端連接請(qǐng)求,生成新的Socket與客戶端通信;
– 客戶端和服務(wù)器端進(jìn)行數(shù)據(jù)傳輸。
二、Linux下Socket編程實(shí)踐
為了更好地理解Socket編程,下面我們介紹一個(gè)簡單的實(shí)例,該實(shí)例演示了如何實(shí)現(xiàn)基本的客戶端和服務(wù)器端之間的消息傳輸。
2.1 服務(wù)器端代碼
下面是基本的服務(wù)器端代碼:
“`
#include
#include
#include
#include
#include
#include
#define PORT 8000
#define MAX_CONN 10
int mn(int argc, char *argv[])
{
int server_fd, client_fd, len;
struct sockaddr_in server_addr, client_addr;
char buffer[1024];
// 創(chuàng)建Socket
if ((server_fd = socket(AF_INET, SOCK_STREAM, 0)) == -1) {
perror(“Cannot create socket”);
exit(1);
}
// 綁定端口
memset(&server_addr, 0, sizeof(server_addr));
server_addr.sin_family = AF_INET;
server_addr.sin_port = htons(PORT);
server_addr.sin_addr.s_addr = htonl(INADDR_ANY);
if (bind(server_fd, (struct sockaddr *)&server_addr, sizeof(server_addr)) == -1) {
perror(“Bind error”);
exit(1);
}
// 監(jiān)聽
if (listen(server_fd, MAX_CONN) == -1) {
perror(“Listen error”);
exit(1);
}
printf(“Server listening on port %d…\n”, PORT);
// 循環(huán)接受連接請(qǐng)求
while (1) {
len = sizeof(client_addr);
if ((client_fd = accept(server_fd, (struct sockaddr *)&client_addr, &len)) == -1) {
perror(“Accept error”);
continue;
}
printf(“Connection established from client %s:%d\n”,
inet_ntoa(client_addr.sin_addr), ntohs(client_addr.sin_port));
// 與客戶端進(jìn)行通信
while (1) {
memset(buffer, 0, sizeof(buffer));
if (recv(client_fd, buffer, sizeof(buffer), 0)
perror(“Recv error”);
break;
}
printf(“Received message from client %s:%d: %s\n”,
inet_ntoa(client_addr.sin_addr), ntohs(client_addr.sin_port), buffer);
if (strncmp(buffer, “exit”, 4) == 0)
break;
if (send(client_fd, buffer, strlen(buffer), 0) == -1) {
perror(“Send error”);
break;
}
}
close(client_fd);
printf(“Connection closed from client %s:%d\n”,
inet_ntoa(client_addr.sin_addr), ntohs(client_addr.sin_port));
}
close(server_fd);
return 0;
}
“`
在該代碼中,我們首先創(chuàng)建了一個(gè)Socket,并綁定了IP地址和端口號(hào)。然后,我們開始監(jiān)聽客戶端的連接請(qǐng)求。當(dāng)有一個(gè)連接請(qǐng)求到來時(shí),我們將生成一個(gè)新的Socket,并通過這個(gè)Socket與客戶端進(jìn)行通信。在與客戶端進(jìn)行通信時(shí),我們可以通過recv()函數(shù)從客戶端接收消息,也可以通過send()函數(shù)向客戶端發(fā)送消息。
2.2 客戶端代碼
下面是基本的客戶端代碼:
“`
#include
#include
#include
#include
#include
#include
#define PORT 8000
int mn(int argc, char *argv[])
{
int client_fd, len;
struct sockaddr_in server_addr;
char buffer[1024];
// 創(chuàng)建Socket
if ((client_fd = socket(AF_INET, SOCK_STREAM, 0)) == -1) {
perror(“Cannot create socket”);
exit(1);
}
// 連接服務(wù)器
memset(&server_addr, 0, sizeof(server_addr));
server_addr.sin_family = AF_INET;
server_addr.sin_port = htons(PORT);
server_addr.sin_addr.s_addr = inet_addr(argv[1]);
if (connect(client_fd, (struct sockaddr *)&server_addr, sizeof(server_addr)) == -1) {
perror(“Connect error”);
exit(1);
}
printf(“Connect to server %s:%d successfully.\n”, argv[1], PORT);
// 與服務(wù)器進(jìn)行通信
while (1) {
printf(“Input message: “);
fgets(buffer, sizeof(buffer), stdin);
if (send(client_fd, buffer, strlen(buffer), 0) == -1) {
perror(“Send error”);
break;
}
if (strncmp(buffer, “exit”, 4) == 0)
break;
memset(buffer, 0, sizeof(buffer));
if (recv(client_fd, buffer, sizeof(buffer), 0)
perror(“Recv error”);
break;
}
printf(“Received message from server: %s”, buffer);
}
close(client_fd);
return 0;
}
“`
在該代碼中,我們首先創(chuàng)建了一個(gè)Socket,并使用該Socket連接了服務(wù)器。在與服務(wù)器進(jìn)行通信時(shí),我們使用fgets()函數(shù)從標(biāo)準(zhǔn)輸入讀取用戶的消息,并使用send()函數(shù)向服務(wù)器發(fā)送消息。同時(shí),在接收服務(wù)器的回復(fù)時(shí),我們通過recv()函數(shù)進(jìn)行接收。
三、
相關(guān)問題拓展閱讀:
- linux下的 socket編程問題!
linux下的 socket編程問題!
1你就打開文件,然后一個(gè)字符一豎伍個(gè)字符的讀文件,然后一個(gè)字符一個(gè)字符的接收,再一個(gè)字符一個(gè)迅纖凳字符寫入文件就行了阿
2這個(gè)問題你問的有點(diǎn)模畝旅糊,服務(wù)器端的編程有很多方式,也不是要每來個(gè)連接就要?jiǎng)?chuàng)建一個(gè)進(jìn)程的。
之一數(shù)桐個(gè)問題:
對(duì),是那樣的,用open打開文件,用read讀取文件,在發(fā)送給對(duì)方,接收方接收到薯碼坦后,寫入文件就可以了。不過在這個(gè)過程中更好別用字符串函數(shù),除非你很熟悉。
第二個(gè)問題
首先你得去搞清楚什么是線程,什么是進(jìn)程,fork出來的叫進(jìn)程,pthread_create出來的才叫線程。服務(wù)器有很多種模型(多進(jìn)程,多線程,select,epoll模型,這個(gè)我的blog上有,famdestiny.cublog.cn),不一定要用多進(jìn)程。
給你寫了個(gè)代碼,自己先看看:
注意,在自己的目錄下創(chuàng)建模知一個(gè)叫pserverb的文件,程序會(huì)把這個(gè)文件復(fù)制成test文件。你可以自己根據(jù)需要改改
server:
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#define SERV_PORT 5358
#define MAX_CONN 10
#define BUF_LEN 1024
void str_echo(FILE *fp, int sockfd){
ssize_t nread;
int file_fd;
char buf = {0};
file_fd = open(“test”, O_WRON | O_TRUNC | O_CREAT, 0755);
while(1) {
bzero(buf, BUF_LEN);
if((nread = read(sockfd, buf, BUF_LEN)) == -1) {
if(errno == EINTR) {
continue;
}
else {
printf(“readn error: %s\n”, strerror(errno));
continue;
}
}
else if (nread == 0) {
break;
}
else {
printf(“%s\n”, buf);
write(file_fd, buf, nread);
}
}
close(file_fd);
}
void sig_chld(int sig){
pid_t pid;
int state;
while((pid = waitpid(-1, &state, WNOHANG)) > 0){
printf(“child process %d exited.”, pid);
}
return;
}
int main(int argc, char **argv)
{
int listenfd, connfd;
socklen_t cliaddrlen;
pid_t childpid;
struct sockaddr_in servaddr, cliaddr;
if((listenfd = socket(AF_INET, SOCK_STREAM, 0)) == -1){
printf(“socket error: %s\n”, strerror(errno));
return 0;
}
bzero(&servaddr, sizeof(servaddr));
servaddr.sin_family = AF_INET;
servaddr.sin_addr.s_addr = htonl(INADDR_ANY);
servaddr.sin_port = htons(SERV_PORT);
if(bind(listenfd, (struct sockaddr *)&servaddr, sizeof(servaddr)) == -1){
printf(“bind error: %s\n”, strerror(errno));
return 0;
}
if(listen(listenfd, MAX_CONN) == -1){
printf(“l(fā)isten error: %s\n”, strerror(errno));
return 0;
}
signal(SIGCHLD, sig_chld);
while(1){
cliaddrlen = sizeof(cliaddr);
if((connfd = accept(listenfd, (struct sockaddr *)&cliaddr, &cliaddrlen)) == -1){
if(errno == EINTR){
continue;
}
else{
printf(“accept error: %s\n”, strerror(errno));
continue;
}
}
if((childpid = fork()) == 0){
close(listenfd);
str_echo(stdin, connfd);
exit(0);
}
else if(childpid > 0){
close(connfd);
}
else{
printf(“fork error!\n”);
continue;
}
}
}
client:
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#define SERV_ADDR “127.0.0.1”
#define SERV_PORT 5358
#define BUF_LEN 1024
void str_cli(char *path, int sockfd)
{
char sendbuf = {0};
int fd, n;
if((fd = open(“./pserverb”, O_RDON)) == -1){
printf(“%s\n”, strerror(errno));
exit(0);
}
while((n = read(fd, sendbuf, BUF_LEN)) != 0) {
if(n
printf(“%s\n”, strerror(errno));
exit(0);
}
write(sockfd, sendbuf, n);
bzero(sendbuf, BUF_LEN);
}
close(fd);
return;
}
int main(int argc, char **argv)
{
int fd;
struct sockaddr_in servaddr;
fd = socket(AF_INET, SOCK_STREAM, 0);
bzero(&servaddr, sizeof(servaddr));
servaddr.sin_family = AF_INET;
servaddr.sin_addr.s_addr = inet_addr(SERV_ADDR);
servaddr.sin_port = htons(SERV_PORT);
if (connect(fd, (struct sockaddr *)&servaddr, sizeof(servaddr)) == -1) {
printf(“connect error: %s\n”, strerror(errno));
return 0;
}
str_cli(argv, fd);
return 0;
}
挖~
關(guān)于linux socket 編程實(shí)例的介紹到此就結(jié)束了,不知道你從中找到你需要的信息了嗎 ?如果你還想了解更多這方面的信息,記得收藏關(guān)注本站。
創(chuàng)新互聯(lián)成都網(wǎng)站建設(shè)公司提供專業(yè)的建站服務(wù),為您量身定制,歡迎來電(028-86922220)為您打造專屬于企業(yè)本身的網(wǎng)絡(luò)品牌形象。
成都創(chuàng)新互聯(lián)品牌官網(wǎng)提供專業(yè)的網(wǎng)站建設(shè)、設(shè)計(jì)、制作等服務(wù),是一家以網(wǎng)站建設(shè)為主要業(yè)務(wù)的公司,在網(wǎng)站建設(shè)、設(shè)計(jì)和制作領(lǐng)域具有豐富的經(jīng)驗(yàn)。
網(wǎng)頁標(biāo)題:Linux下Socket編程:簡單實(shí)例分享(linuxsocket編程實(shí)例)
分享URL:http://www.5511xx.com/article/djjscgo.html


咨詢
建站咨詢
